服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java实现多线程断点下载

Java实现多线程断点下载

2021-04-12 09:25Java之家 Java教程

这篇文章主要为大家详细介绍了Java实现多线程断点下载的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

java多线程断点下载原理如图:

Java实现多线程断点下载

代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import java.io.bufferedreader;
import java.io.file;
import java.io.fileinputstream;
import java.io.inputstream;
import java.io.inputstreamreader;
import java.io.randomaccessfile;
import java.net.httpurlconnection;
import java.net.url;
 
public class mutilethreaddownload {
  /**
   * 线程的数量
   */
  private static int threadcount = 3;
 
  /**
   * 每个下载区块的大小
   */
  private static long blocksize;
 
  /**
   * 正在运行的线程的数量
   */
  private static int runningthreadcount;
 
  /**
   * @param args
   * @throws exception
   */
  public static void main(string[] args) throws exception {
    // 服务器文件的路径
    string path = "http://192.168.1.100:8080/ff.exe";
    url url = new url(path);
    httpurlconnection conn = (httpurlconnection) url.openconnection();
    conn.setrequestmethod("get");
    conn.setconnecttimeout(5000);
    int code = conn.getresponsecode();
    if (code == 200) {
      long size = conn.getcontentlength();// 得到服务端返回的文件的大小
      system.out.println("服务器文件的大小:" + size);
      blocksize = size / threadcount;
      // 1.首先在本地创建一个大小跟服务器一模一样的空白文件。
      file file = new file("temp.exe");
      randomaccessfile raf = new randomaccessfile(file, "rw");
      raf.setlength(size);
      // 2.开启若干个子线程分别去下载对应的资源。
      runningthreadcount = threadcount;
      for (int i = 1; i <= threadcount; i++) {
        long startindex = (i - 1) * blocksize;
        long endindex = i * blocksize - 1;
        if (i == threadcount) {
          // 最后一个线程
          endindex = size - 1;
        }
        system.out.println("开启线程:" + i + "下载的位置:" + startindex + "~"
            + endindex);
        new downloadthread(path, i, startindex, endindex).start();
      }
    }
    conn.disconnect();
  }
 
  private static class downloadthread extends thread {
    private int threadid;
    private long startindex;
    private long endindex;
    private string path;
 
    public downloadthread(string path, int threadid, long startindex,
        long endindex) {
      this.path = path;
      this.threadid = threadid;
      this.startindex = startindex;
      this.endindex = endindex;
    }
 
    @override
    public void run() {
      try {
        // 当前线程下载的总大小
        int total = 0;
        file positionfile = new file(threadid + ".txt");
        url url = new url(path);
        httpurlconnection conn = (httpurlconnection) url
            .openconnection();
        conn.setrequestmethod("get");
        // 接着从上一次的位置继续下载数据
        if (positionfile.exists() && positionfile.length() > 0) {// 判断是否有记录
          fileinputstream fis = new fileinputstream(positionfile);
          bufferedreader br = new bufferedreader(
              new inputstreamreader(fis));
          // 获取当前线程上次下载的总大小是多少
          string lasttotalstr = br.readline();
          int lasttotal = integer.valueof(lasttotalstr);
          system.out.println("上次线程" + threadid + "下载的总大小:"
              + lasttotal);
          startindex += lasttotal;
          total += lasttotal;// 加上上次下载的总大小。
          fis.close();
        }
 
        conn.setrequestproperty("range", "bytes=" + startindex + "-"
            + endindex);
        conn.setconnecttimeout(5000);
        int code = conn.getresponsecode();
        system.out.println("code=" + code);
        inputstream is = conn.getinputstream();
        file file = new file("temp.exe");
        randomaccessfile raf = new randomaccessfile(file, "rw");
        // 指定文件开始写的位置。
        raf.seek(startindex);
        system.out.println("第" + threadid + "个线程:写文件的开始位置:"
            + string.valueof(startindex));
        int len = 0;
        byte[] buffer = new byte[512];
        while ((len = is.read(buffer)) != -1) {
          randomaccessfile rf = new randomaccessfile(positionfile,
              "rwd");
          raf.write(buffer, 0, len);
          total += len;
          rf.write(string.valueof(total).getbytes());
          rf.close();
        }
        is.close();
        raf.close();
 
      } catch (exception e) {
        e.printstacktrace();
      } finally {
        // 只有所有的线程都下载完毕后 才可以删除记录文件。
        synchronized (mutilethreaddownload.class) {
          system.out.println("线程" + threadid + "下载完毕了");
          runningthreadcount--;
          if (runningthreadcount < 1) {
            system.out.println("所有的线程都工作完毕了。删除临时记录的文件");
            for (int i = 1; i <= threadcount; i++) {
              file f = new file(i + ".txt");
              system.out.println(f.delete());
            }
          }
        }
 
      }
    }
  }
}

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

延伸 · 阅读

精彩推荐