package com.coderising.download;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.List;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import com.coderising.download.api.Connection;
import com.coderising.download.api.ConnectionManager;
import com.coderising.download.api.DownloadListener;
import com.google.common.collect.Lists;
public class FileDownloader {
private static final int DEFAULT_THREAD_NUM = 3;
private File downFile = null;
private List<DownloadListener> listeners = Lists.newArrayList();
private CompletionService<Boolean> completionService = new ExecutorCompletionService<Boolean>(
Executors.newFixedThreadPool(5));
private ConnectionManager cm;
private String url;
public FileDownloader(String url) {
this.url = url;
}
public void execute() {
Connection conn = null;
try {
conn = cm.open(this.url);
createFile(conn);
Long length = conn.getContentLength();
int startIndex = 0;
int size = Double.valueOf(Math.ceil(length.intValue()) / DEFAULT_THREAD_NUM).intValue() ;
for (int i = 0; i < DEFAULT_THREAD_NUM; i++) {
conn = cm.open(this.url, startIndex, startIndex + size);
completionService.submit(new DownloadCallable(downFile, conn, startIndex, startIndex + size));
startIndex += size;
}
for (int i = 0; i < DEFAULT_THREAD_NUM; i++) {
try {
if (completionService.take().get()) {
System.out.println("下载成功");
} else {
System.out.println("下载失败");
throw new RuntimeException("下载失败");
}
} catch (Exception e) {
e.printStackTrace();
}
}
for (DownloadListener listener : listeners) {
listener.notifyFinished();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.close();
}
}
}
private boolean createFile(Connection conn) {
RandomAccessFile out = null;
try {
if (downFile == null) {
downFile = new File("/Users/haibo/Code/github/coding2017-1/" + ""
+ "group08/286060098/3-12/src/com/coderising/" + conn.downLoadFileName());
if (downFile.exists()) {
return true;
}
if (downFile.isDirectory()) {
System.out.println("目标文件不能为目录!");
return false;
}
if (!downFile.getParentFile().exists()) {
if (!downFile.getParentFile().mkdirs()) {
System.out.println("创建目标文件所在的目录失败!");
return false;
}
}
try {
if (downFile.createNewFile()) {
System.out.println("创建文件成功");
out = new RandomAccessFile(downFile, "rwd");
out.setLength(conn.getContentLength());
System.out.println(downFile.length());
return true;
} else {
System.out.println("创建文件失败");
return false;
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("创建文件失败" + e.getMessage());
return false;
}
}
return true;
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void addListener(DownloadListener listener) {
this.listeners.add(listener);
}
public void setConnectionManager(ConnectionManager ucm) {
this.cm = ucm;
}
public List<DownloadListener> getListener() {
return this.listeners;
}
}