Java多线程下载文件实例详解

本文实例为大家分享了Java多线程下载文件的具体代码,供大家参考,具体内容如下

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL; 

public class MulThreadDownload {
  public static void main(String[] args) throws Exception {
    String path = "http://192.168.1.100:8080/Hello/Big.exe";
    new MulThreadDownload().download(path, 3);
  } 

  /**
   * 下载文件
   *
   * @param path
   *      网络文件路径
   * @param threadSize
   *      线程数
   * @throws Exception
   */
  private void download(String path, int threadSize) throws Exception {
    URL url = new URL(path);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("GET");
    connection.setConnectTimeout(5000);
    if (connection.getResponseCode() == 200) {
      int length = connection.getContentLength();// 获取网络文件长度
      File file = new File(getFileName(path));
      // 在本地生成一个长度与网络文件相同的文件
      RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
      accessFile.setLength(length);
      accessFile.close(); 

      // 计算每条线程负责下载的数据量
      int block = length % threadSize == 0 ? length / threadSize : length
          / threadSize + 1;
      for (int threadId = 0; threadId < threadSize; threadId++) {
        new DownloadThread(threadId, block, url, file).start();
      }
    } else {
      System.out.println("download fail");
    }
  } 

  private class DownloadThread extends Thread { 

    private int threadId;
    private int block;
    private URL url;
    private File file; 

    public DownloadThread(int threadId, int block, URL url, File file) {
      this.threadId = threadId;
      this.block = block;
      this.url = url;
      this.file = file;
    } 

    @Override
    public void run() {
      int start = threadId * block; // 计算该线程从网络文件什么位置开始下载
      int end = (threadId + 1) * block - 1; // 计算下载到网络文件什么位置结束
      try {
        RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
        accessFile.seek(start); //从start开始 

        HttpURLConnection connection = (HttpURLConnection) url
            .openConnection();
        connection.setRequestMethod("GET");
        connection.setConnectTimeout(5000);
        //设置获取资源数据的范围,从start到end
        connection.setRequestProperty("Range", "bytes=" + start + "-"
            + end);
        //注意多线程下载状态码是 206 不是200
        if (connection.getResponseCode() == 206) {
          InputStream inputStream = connection.getInputStream();
          byte[] buffer = new byte[1024];
          int len = 0;
          while ((len = inputStream.read(buffer)) != -1) {
            accessFile.write(buffer, 0, len);
          }
          accessFile.close();
          inputStream.close();
        }
        System.out.println("第" + (threadId + 1) + "条线程已经下载完成");
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  } 

  /**
   * 获取文件名称
   *
   * @param path
   *      网络文件路径
   * @return
   */
  private String getFileName(String path) {
    return path.substring(path.lastIndexOf("/") + 1);
  }
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2017-04-04

Java编程之多线程死锁与线程间通信简单实现代码

死锁定义 死锁是指两个或者多个线程被永久阻塞的一种局面,产生的前提是要有两个或两个以上的线程,并且来操作两个或者多个以上的共同资源:我的理解是用两个线程来举例,现有线程A和B同时操作两个共同资源a和b,A操作a的时候上锁LockA,继续执行的时候,A还需要LockB进行下面的操作,这个时候b资源在被B线程操作,刚好被上了锁LockB,假如此时线程B刚好释放了LockB则没有问题,但没有释放LockB锁的时候,线程A和B形成了对LockB锁资源的争夺,从而造成阻塞,形成死锁:具体其死锁代码如下:

Java 多线程有序执行的几种方法总结

Java 多线程有序执行的几种方法总结 同事无意间提出了这个问题,亲自实践了两种方法.当然肯定还会有更多更好的方法. 方法一 import java.util.concurrent.atomic.AtomicInteger; public class OrderedThread1 { static AtomicInteger count = new AtomicInteger(0); public static void main(String[] args) throws Interrupte

简单谈谈RxJava和多线程并发

前言 相信对于RxJava,大家应该都很熟悉,他最核心的两个字就是异步,诚然,它对异步的处理非常的出色,但是异步绝对不等于并发,更不等于线程安全,如果把这几个概念搞混了,错误的使用RxJava,是会来带非常多的问题的. RxJava与并发 首先让我们来看一段RxJava协议的原文: Observables must issue notifications to observers serially (not in parallel). They may issue these notificat

java实现多线程之定时器任务

在Java中Timer是java.util包中的一个工具类,提供了定时器的功能.我们可以创建一个Timer对象,然后调用其schedule方法在某个特定的时间去执行一个特定的任务.并且你可以让其以特定频率一直执行某个任务,这个任务是用TimerTask来描述的,我们只需要将要进行的操作写在TimerTask类的run方法中即可.先附上两个小例子一遍让读者了解什么是定时器.接着再分析其中的一些源码实现. 第一个小例子: package com.zkn.newlearn.thread; import

Java实现多线程文件下载的代码示例

Java实现多线程文件下载思路: 1.基本思路是将文件分段切割.分段传输.分段保存. 2.分段切割用到HttpUrlConnection对象的setRequestProperty("Range", "bytes=" + start + "-" + end)方法. 3.分段传输用到HttpUrlConnection对象的getInputStream()方法. 4.分段保存用到RandomAccessFile的seek(int start)方法. 5

Java编程利用socket多线程访问服务器文件代码示例

这篇文章将向大家展示Java编程利用socket多线程访问服务器文件代码示例,如果您想先了解Java多线程socket编程的基础知识,可以看下这篇文章:Java多线程编程实现socket通信示例代码. 接下来进入正文,我们看看利用socket多线程访问服务器代码: ServerMain.java package com.ysk.webServer; import java.io.File; import java.io.IOException; import java.net.ServerSoc

Java创建与结束线程代码示例

本文讲述了在Java中如何创建和结束线程的最基本方法,只针对于Java初学者.一些高级知识如线程同步.调度.线程池等内容将会在后续章节中逐步深入. 创建线程 创建普通线程有两种方式,继承Thread类或实现Runnable接口.示例如下. 方法1:继承Thread类 创建方法示例: public class MyThread1 extends Thread { @Override public void run() { //TODO Auto-generated method stub supe

Java语言实现反转链表代码示例

问题描述 定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的链表的头结点.链表结点如下: public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } 思路1: 要想反转链表,对于结点i,我们要把它的next指向它的前趋,因此我们需要保存前趋结点,同时,如果我们已经把i的next重新赋值,会无法找到i的后继,因此,在重新赋值之前,我们要保存i的后继. 代码:

Java实现四则混合运算代码示例

使用栈来实现,可以处理运算优先级. 使用自然四则运算表达式即可,如:4+(3*(3-1)+2)/2.无需把表达式先转换为逆波兰等形式. package com.joshua.cal; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; im

Java编程之继承问题代码示例

课堂练习: –在包bzu.aa中定义一个交通工具类(Vehicle): 1.属性--载客量(capacity) 2.方法 (1)无参构造方法(给capacity初始化值为2,并输出"执行交通工具类的无参构造方法.") (2)有参构造方法(传参给capacity初始化,并输出"执行交通工具的有参构造方法.") (3)capacity的set.get方法 (4)print方法:输出capacity –在包bzu.aa中定义一个汽车类(Car)继承交通工具类: 1.属性-

Java map的学习及代码示例

前言 最近正在做的高校云平台项目中接触Map比较多,关于map的使用不是很熟悉,所以在此将map的几个方法再次学习下. Map与Collection 提到Map集合接口就不能不提到Collection集合接口,map和Collection都是集合接口,Collection中包含了我们经常用的list和set子接口:而Map是与Collection处于平级的地位:Collection中存储的是一组对象,而Map存储的是一个键值对(key/value). Map java为数据结构中的映射定义了一个

Java编程实现帕斯卡三角形代码示例

源程序揭秘 杨辉三角形性质: 每行数字左右对称,由 1 开始逐渐变大,然后变小,回到 1. 第 n 行的数字个数为 n 个. 第 n 行数字和为 2^(n-1) . 每个数字等于上一行的左右两个数字之和.可用此性质写出整个杨辉三角形. 第 n 行的第 1 个数为 1,第二个数为 1× (n-1) ,第三个数为 1× (n-1) × ( n-2) /2,第四个数为 1× (n-1) × (n-2) /2× (n-3) /3-依此类推. 算法原理1: 使用一个二维数组 yh[][] 存储杨辉三角形的

java 导入Excel思路及代码示例

导出就是将List转化为Excel(listToExcel) 导入就是将Excel转化为List(excelToList) 一.思路分析 1.我们要做导入,实际上也就是先文件上传,然后读取文件的数据. 2.我们要有一个导入的模板,因为我们导入的Excel列要和我们的数据字段匹配上,所以我们要给它来一个规定,也就是模板. 3.按照我们公司的套路,是做了一个导入信息的临时表,用来存导入文件中的信息.每当导入的时候,我们先把表信息清空,再拿到数据放进来,然后我们对导入的数据进行检查,最后才全部导入.

Java将字符串写入文本文件代码示例

一.Filewriter与File---将字符串写入文本文件 public static void main(String[] args) { File f=new File("C:\\world.txt");//新建一个文件对象,如果不存在则创建一个该文件 FileWriter fw; try { fw=new FileWriter(f); String str="hello world"; fw.write(str);//将字符串写入到指定的路径下的文件中 fw