Skip to content

Commit

Permalink
Merge pull request #12 from laibinCN/master
Browse files Browse the repository at this point in the history
0312 作业
  • Loading branch information
CoderXLoong authored Mar 13, 2017
2 parents 7f700c2 + 77446fd commit 98fc3cd
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 0 deletions.
44 changes: 44 additions & 0 deletions group13/568334413/0312/download/DownloadThread.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package download;


import download.api.Connection;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.CountDownLatch;

public class DownloadThread extends Thread {

private CountDownLatch countDownLatch;
Connection conn;
int startPos;
int endPos;

public DownloadThread(Connection conn, int startPos, int endPos, CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
this.conn = conn;
this.startPos = startPos;
this.endPos = endPos;
}

@Override
public void run() {
try {
byte[] bytes = conn.read(startPos, endPos);
if (bytes == null) {
return;
}
File file = new File("./src/main/resources/1.mp4");
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
randomAccessFile.seek(0);
randomAccessFile.write(bytes);
randomAccessFile.close();
countDownLatch.countDown();

} catch (IOException e) {
e.printStackTrace();
}

}
}
76 changes: 76 additions & 0 deletions group13/568334413/0312/download/FileDownloader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package download;

import download.api.Connection;
import download.api.ConnectionManager;
import download.api.DownloadListener;

import java.util.concurrent.CountDownLatch;

public class FileDownloader {

String url;
DownloadListener listener;
ConnectionManager cm;
int THREADCOUNT = 4;

public FileDownloader(String _url) {
this.url = _url;
}

public void execute() {
// 在这里实现你的代码, 注意: 需要用多线程实现下载
// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
// (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定)
// (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有
// 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。
// 具体的实现思路:
// 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度
//
// 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法
// 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组
//
// 3. 把byte数组写入到文件中
//
// 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法
// 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。
Connection conn = null;
try {
conn = cm.open(this.url);
int length = conn.getContentLength();

int blockSize = length / THREADCOUNT;
final CountDownLatch countDownLatch = new CountDownLatch(THREADCOUNT);
for (int threadId = 0; threadId < THREADCOUNT; threadId++) {
int startIndex = threadId * blockSize;
int endIndex = (threadId + 1) * blockSize - 1;
if (threadId == (THREADCOUNT - 1)) {
endIndex = length - 1;
}
new DownloadThread(conn, startIndex, endIndex, countDownLatch).start();
}
countDownLatch.await();
getListener().notifyFinished();

} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.close();
}
}
}

public void setListener(DownloadListener listener) {
this.listener = listener;
}


public void setConnectionManager(ConnectionManager ucm) {
this.cm = ucm;
}

public DownloadListener getListener() {
return this.listener;
}

}
56 changes: 56 additions & 0 deletions group13/568334413/0312/download/FileDownloaderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package download;


import download.api.ConnectionManager;
import download.api.DownloadListener;
import download.impl.ConnectionManagerImpl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class FileDownloaderTest {
boolean downloadFinished = false;

@Before
public void setUp() throws Exception {
}

@After
public void tearDown() throws Exception {
}

@Test
public void testDownload() {

// String url = "http://upload-images.jianshu.io/upload_images/430632-49ce383d76352277.jpg";
// String url = "http://img3.91.com/uploads/allimg/130428/32-13042Q63239.jpg";
// String url = "http://images.weiphone.net/data/attachment/forum/201703/10/082621it8dfr8frmpbgrdo.png";
String url = "http://img.zhxhlm.com/o_1b4sfgd8087os528sg85jjkf.mp4";
FileDownloader downloader = new FileDownloader(url);
ConnectionManager cm = new ConnectionManagerImpl();
downloader.setConnectionManager(cm);
downloader.setListener(new DownloadListener() {

public void notifyFinished() {
downloadFinished = true;
}
});
downloader.execute();

// 等待多线程下载程序执行完毕
while (!downloadFinished) {
try {
System.out.println("还没有下载完成,休眠五秒");
//休眠5秒
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println("下载完成!");


}

}
27 changes: 27 additions & 0 deletions group13/568334413/0312/download/api/Connection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package download.api;

import java.io.IOException;

public interface Connection {
/**
* 给定开始和结束位置, 读取数据, 返回值是字节数组
*
* @param startPos 开始位置, 从0开始
* @param endPos 结束位置
* @return
*/
public byte[] read(int startPos, int endPos) throws IOException;

/**
* 得到数据内容的长度
*
* @return
*/
public int getContentLength() throws IOException;


/**
* 关闭连接
*/
public void close();
}
5 changes: 5 additions & 0 deletions group13/568334413/0312/download/api/ConnectionException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package download.api;

public class ConnectionException extends Exception {

}
12 changes: 12 additions & 0 deletions group13/568334413/0312/download/api/ConnectionManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package download.api;

import java.io.IOException;

public interface ConnectionManager {
/**
* 给定一个url , 打开一个连接
* @param url
* @return
*/
public Connection open(String url) throws ConnectionException, IOException;
}
5 changes: 5 additions & 0 deletions group13/568334413/0312/download/api/DownloadListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package download.api;

public interface DownloadListener {
public void notifyFinished();
}
88 changes: 88 additions & 0 deletions group13/568334413/0312/download/impl/ConnectionImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package download.impl;

import download.api.Connection;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;


public class ConnectionImpl implements Connection {

private static int RESPONSECODE = 200;
private String urlAddress;
private InputStream inputStream;
private HttpURLConnection httpURLConnection = null;
private URL url = null;

public ConnectionImpl(String urlAddress) {
this.urlAddress = urlAddress;
try {
url = new URL(urlAddress);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setConnectTimeout(10000);
httpURLConnection.setRequestMethod("GET");
httpURLConnection.connect();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

public byte[] read(int startPos, int endPos) {

HttpURLConnection httpURLConnection = null;
try {
httpURLConnection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setConnectTimeout(10000);
byte[] tempByteArray = new byte[0];
try {
httpURLConnection.setRequestMethod("GET");
httpURLConnection.connect();
tempByteArray = new byte[httpURLConnection.getContentLength()];
InputStream inputStream = httpURLConnection.getInputStream();
byte[] buffer = new byte[1024];
int len = -1;
int index = 0;
while ((len = inputStream.read(buffer)) != -1) {
System.arraycopy(buffer, 0, tempByteArray, index, len);
index = index + len;
}
inputStream.close();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return tempByteArray;
}

public int getContentLength() throws IOException {
int code = httpURLConnection.getResponseCode();
if (code == RESPONSECODE) {
inputStream = httpURLConnection.getInputStream();
return httpURLConnection.getContentLength();
}
return 0;
}

public void close() {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
20 changes: 20 additions & 0 deletions group13/568334413/0312/download/impl/ConnectionManagerImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package download.impl;


import download.api.Connection;
import download.api.ConnectionException;
import download.api.ConnectionManager;

import java.io.IOException;

public class ConnectionManagerImpl implements ConnectionManager {


public Connection open(String address) throws ConnectionException, IOException {

Connection connection = new ConnectionImpl(address);

return connection;
}

}

0 comments on commit 98fc3cd

Please sign in to comment.