代碼如下:
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 { /** * 線程的數(shù)量 */ private static int threadcount = 3 ; /** * 每個下載區(qū)塊的大小 */ private static long blocksize; /** * 正在運行的線程的數(shù)量 */ 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.首先在本地創(chuàng)建一個大小跟服務器一模一樣的空白文件。 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" ); // 接著從上一次的位置繼續(xù)下載數(shù)據(jù) 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()); } } } } } } } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。