Skip to content

Commit

Permalink
Merge pull request #26 from Pxshuo163/master
Browse files Browse the repository at this point in the history
作业补交
  • Loading branch information
diliuzuzhanghao authored Apr 5, 2017
2 parents e62fb21 + c5d0c5c commit 1edc45f
Show file tree
Hide file tree
Showing 17 changed files with 1,383 additions and 52 deletions.
Binary file added group06/2415980327/CodeSE01/down2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
456 changes: 456 additions & 0 deletions group06/2415980327/CodeSE01/src/com/pxshuo/se03/basic/LinkedList.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.pxshuo.se03.basic;

public interface List {
public void add(Object o);
public void add(int index, Object o);
public Object get(int index);
public Object remove(int index);
public int size();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.pxshuo.se03.download;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

import com.pxshuo.se03.download.api.Connection;

public class DownloadThread extends Thread{

Connection conn;
int startPos;
int endPos;

CyclicBarrier barrier;
String localFile;

public DownloadThread( Connection conn, int startPos, int endPos,String localFile,CyclicBarrier barrier){

this.conn = conn;
this.startPos = startPos;
this.endPos = endPos;

this.localFile = localFile;
this.barrier = barrier;
}
public void run(){
System.out.println("Begin to read [" + startPos + "-" + endPos + "]");
try {
byte[] data = conn.read(startPos, endPos);
RandomAccessFile file = new RandomAccessFile(localFile, "rw");

file.seek(startPos);
file.write(data);
file.close();

conn.close();
barrier.await();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package com.pxshuo.se03.download;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.CyclicBarrier;

import com.pxshuo.se03.download.api.Connection;
import com.pxshuo.se03.download.api.ConnectionException;
import com.pxshuo.se03.download.api.ConnectionManager;
import com.pxshuo.se03.download.api.DownloadListener;


public class FileDownloader {

private final static int DOWNLOAD_THREAD_NUM = 3;

private String url;
private String filePath;

DownloadListener listener;

ConnectionManager cm;


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

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方法

// 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。
CyclicBarrier cyclicBarrier = new CyclicBarrier(DOWNLOAD_THREAD_NUM,new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
listener.notifyFinished();
}
});

Connection conn = null;
try {

conn = cm.open(this.url);

int length = conn.getContentLength();
System.out.println(length);

createPlaceHolderFile(this.filePath, length);

int[][] ranges = allocateDownloadRange(DOWNLOAD_THREAD_NUM, length);

for(int i = 0; i < DOWNLOAD_THREAD_NUM; i++){
DownloadThread thread = new DownloadThread(
cm.open(url),
ranges[i][0],
ranges[i][1],
filePath,
cyclicBarrier);

thread.start();
}

} catch (ConnectionException | IOException 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;
}

/**
* 先在硬盘中占据一部分空间
* @param filePath
* @param length
* @throws IOException
*/
private void createPlaceHolderFile(String filePath,int length) throws IOException{
RandomAccessFile file = new RandomAccessFile(filePath, "rw");

for (int i = 0; i < length; i++) {//初始化一个文件
file.write(0);
}

file.close();
}

private int[][] allocateDownloadRange(int threadNum,int length){
int[][] ranges = new int[threadNum][2];

int eachThreadSize = length/threadNum;
int left = length % threadNum;

for (int i = 0; i < threadNum; i++) {
int startPos = i * eachThreadSize;
int endPos = (i + 1) * eachThreadSize - 1;

if (i == (threadNum - 1)) {
endPos += left;
}

ranges[i][0] = startPos;
ranges[i][1] = endPos;
}

return ranges;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.pxshuo.se03.download;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.pxshuo.se03.download.api.ConnectionManager;
import com.pxshuo.se03.download.api.DownloadListener;
import com.pxshuo.se03.download.impl.ConnectionManagerImpl;

public class FileDownloaderTest {
boolean downloadFinished = false;
@Before
public void setUp() throws Exception {
}

@After
public void tearDown() throws Exception {
}

public static void main(String[] args) {
FileDownloaderTest test = new FileDownloaderTest();
test.testDownload();
}

public void testDownload() {

String url = "https://gss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/3c6d55fbb2fb4316352d920a22a4462309f7d394.jpg";
String filePath = "C://Users//Pxshuo//Desktop//test.png";

FileDownloader downloader = new FileDownloader(url,filePath);


ConnectionManager cm = new ConnectionManagerImpl();
downloader.setConnectionManager(cm);

downloader.setListener(new DownloadListener() {
@Override
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("下载完成!");



}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.pxshuo.se03.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();

/**
* 关闭连接
*/
public void close();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.pxshuo.se03.download.api;

public class ConnectionException extends Exception {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.pxshuo.se03.download.api;

public interface ConnectionManager {
/**
* 给定一个url , 打开一个连接
* @param url
* @return
*/
public Connection open(String url) throws ConnectionException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.pxshuo.se03.download.api;

public interface DownloadListener {
public void notifyFinished();
}
Loading

0 comments on commit 1edc45f

Please sign in to comment.