Skip to content

Commit e86803d

Browse files
committed
Ralf
1 parent 7436f62 commit e86803d

12 files changed

+974
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.coderising.download;
2+
3+
import java.io.File;
4+
import java.io.FileNotFoundException;
5+
import java.io.IOException;
6+
import java.io.RandomAccessFile;
7+
8+
import com.coderising.download.api.Connection;
9+
import com.coderising.download.api.ConnectionException;
10+
import com.coderising.download.api.ConnectionManager;
11+
import com.coderising.download.api.DownloadListener;
12+
13+
public class DownloadThread extends Thread {
14+
15+
16+
ConnectionManager cm;
17+
int startPos;
18+
int endPos;
19+
String url;
20+
DownloadListener downloadListener;
21+
22+
public DownloadThread(ConnectionManager cm, String url, int startPos, int endPos, DownloadListener listener) {
23+
24+
this.cm = cm;
25+
this.startPos = startPos;
26+
this.endPos = endPos;
27+
this.url = url;
28+
this.downloadListener = listener;
29+
}
30+
31+
@Override
32+
public void run() {
33+
34+
Connection conn = null;
35+
RandomAccessFile raf = null;
36+
// 随机写文件的时候从哪个位置开始写
37+
try {
38+
conn = cm.open(url,startPos,endPos);
39+
} catch (ConnectionException e3) {
40+
// TODO Auto-generated catch block
41+
e3.printStackTrace();
42+
}
43+
44+
try {
45+
46+
byte[] byeArr = conn.read(startPos, endPos);
47+
System.out.println("----::" + byeArr.length);
48+
File file = new File("D:\\111.jpg");
49+
synchronized (file) {
50+
if (!file.exists()) {
51+
file.createNewFile();
52+
}
53+
raf = new RandomAccessFile(file, "rw");
54+
}
55+
//raf.setLength(34134);
56+
raf.seek(startPos);// 定位文件
57+
raf.write(byeArr);
58+
59+
System.out.println("-------");
60+
61+
} catch (FileNotFoundException e1) {
62+
// TODO Auto-generated catch block
63+
e1.printStackTrace();
64+
} catch (IOException e) {
65+
e.printStackTrace();
66+
} finally {
67+
try {
68+
if (raf != null) {
69+
raf.close();
70+
}
71+
72+
} catch (Exception e2) {
73+
// TODO: handle exception
74+
e2.printStackTrace();
75+
}
76+
if (conn != null) {
77+
conn.close();
78+
}
79+
if (downloadListener != null) {
80+
downloadListener.notifyFinished();
81+
}
82+
83+
}
84+
}
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.coderising.download;
2+
3+
import com.coderising.download.api.ConnectionManager;
4+
import com.coderising.download.api.DownloadListener;
5+
6+
public class FileDownloader {
7+
8+
String url;
9+
DownloadListener listener;
10+
ConnectionManager cm;
11+
int threadSum = 0;
12+
13+
public FileDownloader(String _url) {
14+
this.url = _url;
15+
16+
}
17+
18+
public void execute() {
19+
// 在这里实现你的代码, 注意: 需要用多线程实现下载
20+
// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
21+
// (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos,
22+
// endPos来指定)
23+
// (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有
24+
// 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。
25+
// 具体的实现思路:
26+
// 1. 需要调用ConnectionManager的open方法打开连接,
27+
// 然后通过Connection.getContentLength方法获得文件的长度
28+
// 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法
29+
// 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组
30+
// 3. 把byte数组写入到文件中
31+
// 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法
32+
33+
// 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。
34+
// Connection conn = null;
35+
36+
int threadNum = 3;
37+
38+
int length = cm.getContentLength(url);
39+
for (int i = 0; i < threadNum; i++) {
40+
41+
int threadLoadLength = length / threadNum;
42+
int startPos = threadLoadLength * i;
43+
int endPos;
44+
if (i != threadNum - 1) {
45+
endPos = threadLoadLength * (i + 1) - 1;
46+
} else {
47+
endPos = length - 1;
48+
}
49+
threadSum++;
50+
new DownloadThread(cm, this.url, startPos, endPos, new DownloadListener() {
51+
@Override
52+
public void notifyFinished() {
53+
if ((threadSum--) == 0) {
54+
if (listener != null) {
55+
listener.notifyFinished();
56+
}
57+
}
58+
}
59+
}).start();
60+
61+
}
62+
}
63+
64+
public void setListener(DownloadListener listener) {
65+
this.listener = listener;
66+
}
67+
68+
public void setConnectionManager(ConnectionManager ucm) {
69+
this.cm = ucm;
70+
}
71+
72+
public DownloadListener getListener() {
73+
return this.listener;
74+
}
75+
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.coderising.download;
2+
3+
import org.junit.After;
4+
import org.junit.Before;
5+
import org.junit.Test;
6+
7+
import com.coderising.download.api.ConnectionManager;
8+
import com.coderising.download.api.DownloadListener;
9+
import com.coderising.download.impl.ConnectionManagerImpl;
10+
11+
public class FileDownloaderTest {
12+
boolean downloadFinished = false;
13+
@Before
14+
public void setUp() throws Exception {
15+
}
16+
17+
@After
18+
public void tearDown() throws Exception {
19+
}
20+
21+
@Test
22+
public void testDownload() {
23+
24+
String url = "http://img002.21cnimg.com/photos/album/20160326/m600/B920004B5414AE4C7D6F2BAB2966491E.jpeg";
25+
26+
FileDownloader downloader = new FileDownloader(url);
27+
28+
29+
ConnectionManager cm = new ConnectionManagerImpl();
30+
downloader.setConnectionManager(cm);
31+
32+
downloader.setListener(new DownloadListener() {
33+
@Override
34+
public void notifyFinished() {
35+
downloadFinished = true;
36+
}
37+
38+
});
39+
40+
41+
downloader.execute();
42+
43+
// 等待多线程下载程序执行完毕
44+
45+
while (!downloadFinished) {
46+
try {
47+
System.out.println("还没有下载完成,休眠五秒");
48+
//休眠5秒
49+
Thread.sleep(5000);
50+
} catch (InterruptedException e) {
51+
e.printStackTrace();
52+
}
53+
}
54+
System.out.println("下载完成!");
55+
56+
}
57+
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.coderising.download.api;
2+
3+
import java.io.IOException;
4+
5+
public interface Connection {
6+
/**
7+
* 给定开始和结束位置, 读取数据, 返回值是字节数组
8+
* @param startPos 开始位置, 从0开始
9+
* @param endPos 结束位置
10+
* @return
11+
*/
12+
public byte[] read(int startPos,int endPos) throws IOException;
13+
/**
14+
* 得到数据内容的长度
15+
* @return
16+
*/
17+
public int getContentLength();
18+
19+
/**
20+
* 关闭连接
21+
*/
22+
public void close();
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.coderising.download.api;
2+
3+
public class ConnectionException extends Exception {
4+
5+
/**
6+
*
7+
*/
8+
private static final long serialVersionUID = 4776347926322882920L;
9+
10+
/**
11+
*
12+
*/
13+
public ConnectionException(){
14+
super();
15+
}
16+
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.coderising.download.api;
2+
3+
public interface ConnectionManager {
4+
/**
5+
* 给定一个url , 打开一个连接
6+
* @param url
7+
* @return
8+
*/
9+
//public Connection open(String url) throws ConnectionException;
10+
11+
public int getContentLength(String url);
12+
13+
Connection open(String url, int startPos, int endPos)
14+
throws ConnectionException;
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.coderising.download.api;
2+
3+
public interface DownloadListener {
4+
public void notifyFinished();
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.coderising.download.impl;
2+
3+
import java.io.ByteArrayOutputStream;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.net.HttpURLConnection;
7+
8+
import com.coderising.download.api.Connection;
9+
10+
public class ConnectionImpl implements Connection{
11+
12+
private HttpURLConnection httpConn;
13+
private InputStream inputStream;
14+
15+
public ConnectionImpl(HttpURLConnection httpconn) {
16+
// TODO Auto-generated constructor stub
17+
this.httpConn = httpconn;
18+
}
19+
20+
21+
//read() 方法有问题
22+
@Override
23+
public byte[] read(int startPos, int endPos) throws IOException {
24+
25+
inputStream = httpConn.getInputStream();
26+
27+
System.out.println(startPos + "----" + endPos);
28+
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
29+
int len = 0;
30+
byte[] by = new byte[1024];
31+
32+
while((len = inputStream.read(by))!= -1){
33+
byteArrayOutputStream.write(by, 0, len);
34+
}
35+
System.out.println(byteArrayOutputStream.toByteArray().length);
36+
return byteArrayOutputStream.toByteArray();
37+
38+
}
39+
40+
@Override
41+
public int getContentLength() {
42+
if (httpConn != null) {
43+
return httpConn.getContentLength();
44+
}
45+
return 0;
46+
}
47+
48+
@Override
49+
public void close() {
50+
if (inputStream != null) {
51+
try {
52+
inputStream.close();
53+
} catch (IOException e) {
54+
// TODO Auto-generated catch block
55+
e.printStackTrace();
56+
}
57+
}
58+
if (httpConn != null) {
59+
httpConn.disconnect();
60+
}
61+
62+
}
63+
64+
}

0 commit comments

Comments
 (0)