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
|
<pre name=
"code"
class
=
"java"
>
package
com.zengtao.tools;
import
java.io.InputStream;
import
java.io.RandomAccessFile;
import
java.net.HttpURLConnection;
import
java.net.URL;
public
class
DemoLoader {
private
static
DemoLoader loader =
new
DemoLoader();
private
static
int
threadCount =
3
;
private
DemoLoader() {
}
// 单例设计模式
public
static
DemoLoader getInstance() {
return
loader;
}
public
void
downFile(String path) {
// 去服务器端获取文件的长度,在本地创建一个跟服务器一样大小的文件
try
{
URL url =
new
URL(path);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(
true
);
connection.setRequestMethod(
"GET"
);
connection.setReadTimeout(
5000
);
int
code = connection.getResponseCode();
if
(code ==
200
) {
// 获取服务器端文件的长度
int
fileLength = connection.getContentLength();
// 本地创建一个跟服务器一样大小的文件
RandomAccessFile raf =
new
RandomAccessFile(
"setup.ext"
,
"rwd"
);
raf.setLength(fileLength);
raf.close();
// 假设三个线程下载
int
blockSize = fileLength / threadCount;
for
(
int
threadId =
0
; threadId < threadCount; threadId++) {
int
startIndex = (threadId -
1
) * blockSize;
int
endIndex = threadId * blockSize -
1
;
if
(threadId == threadCount) {
endIndex = fileLength;
}
System.out.println(
"线程:"
+ threadId +
",下载:"
+ startIndex
+
"--->"
+ endIndex);
// 开始下载
new
DownLoadThread(threadId, startIndex, endIndex, path)
.start();
}
System.out.println(
"文件总长度为:"
+ fileLength);
}
else
{
System.out.println(
"请求失败!"
);
}
}
catch
(Exception e) {
e.printStackTrace();
}
}
/**
* 下载文件的主线程
*
* @author Administrator zengtao
*
*/
public
class
DownLoadThread
extends
Thread {
private
int
threadId;
private
int
startIndex;
private
int
endIndex;
private
String path;
/**
*
* @param threadId
* 线程id
* @param startIndex
* 线程下载开始位置
* @param endIndex
* 线程下载结束位置
* @param path
* 线程下载结束文件放置地址
*/
public
DownLoadThread(
int
threadId,
int
startIndex,
int
endIndex,
String path) {
super
();
this
.threadId = threadId;
this
.startIndex = startIndex;
this
.endIndex = endIndex;
this
.path = path;
}
@Override
public
void
run() {
super
.run();
URL url;
try
{
url =
new
URL(path);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
// 请求服务器下载部分的文件,制定开始的位置,和结束位置
connection.setRequestProperty(
"Range"
,
"bytes="
+ startIndex
+
"-"
+ endIndex);
connection.setDoInput(
true
);
connection.setRequestMethod(
"GET"
);
connection.setReadTimeout(
5000
);
// 从服务器获取的全部数据,返回:200,从服务器获取部分数据,返回:206
int
code = connection.getResponseCode();
System.out.println(
"code = "
+ code);
InputStream is = connection.getInputStream();
RandomAccessFile raf =
new
RandomAccessFile(
"setup.exe"
,
"rwd"
);
// 随机写文件的时候,从什么时候开始
raf.seek(startIndex);
int
len =
0
;
byte
[] buff =
new
byte
[
1024
];
while
((len = is.read(buff)) != -
1
) {
raf.write(buff,
0
, len);
}
is.close();
raf.close();
System.out.println(
"线程:"
+ threadId +
",下载完成"
);
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
}</pre>
|
Android 之多线程下载原理
最新推荐文章于 2022-12-27 17:10:26 发布