Java多线程下载文件
来源:互联网 发布:sql查询字段是否相等 编辑:程序博客网 时间:2024/04/29 14:15
Java多线程下载文件
文件下载采用多线程方式能够充分利用CPU资源,关键点是设置线程的读取开始和结束位置。下面的代码,采用线程池启动10个线程来执行下载
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FileDownLoadTest {
private static final int TCOUNT = 10;
/** 10个线程 */
private CountDownLatch latch = new CountDownLatch(TCOUNT);
private long completeLength = 0;
/**
* 文件总长度,单位bytes
*/
private long fileLength;
public static void main(String[] args) throws Exception {
new FileDownLoadTest().download("http://localhost:8080/test/IESSAction.docx");
}
public void download(String address) throws Exception {
ExecutorService service = Executors.newFixedThreadPool(TCOUNT);
URL url = new URL(address);
URLConnection cn = url.openConnection();
cn.setRequestProperty("Referer", "http://www.test.com");
fileLength = cn.getContentLength();
//每个线程读取的长度
long packageLength = fileLength / TCOUNT;
//文件平均分给10个线程读取,如果不能平均分配,则剩余的长度为leftLength
long leftLength = fileLength % TCOUNT;
RandomAccessFile file = new RandomAccessFile("d:\\test.docx", "rw");
//计算每个线程请求文件的开始和结束位置
long pos = 0;
long endPos = pos + packageLength;
for (int i = 0; i < TCOUNT; i++) {
if (leftLength > 0) {
endPos++;
leftLength--;
}
service.execute(new DownLoadThread(url, file, pos, endPos));
pos = endPos;
endPos = pos + packageLength;
}
System.out.println("waiting........................................");
long begin = System.currentTimeMillis();
latch.await();
file.close();
System.out.println("end........................................");
System.out.println(System.currentTimeMillis() - begin + "ms");
service.shutdown();
}
class DownLoadThread implements Runnable {
private URL url;
private RandomAccessFile file;
private long from;
private long end;
DownLoadThread(URL url, RandomAccessFile file, long from, long end) {
this.url = url;
this.file = file;
this.from = from;
this.end = end;
}
public void run() {
long pos = from;
byte[] buf = new byte[512];
try {
HttpURLConnection cn = (HttpURLConnection) url.openConnection();
cn.setRequestProperty("Range", "bytes=" + from + "-" + end);
if (cn.getResponseCode() != 200 && cn.getResponseCode() != 206) {
run();
return;
}
BufferedInputStream bis = new BufferedInputStream(cn.getInputStream());
int len;
while ((len = bis.read(buf)) != -1) {
file.seek(pos);
file.write(buf, 0, len);
pos += len;
completeLength += len;
System.out.println("threadName: "
+ Thread.currentThread().getName() + "persent: "
+ completeLength * 100 / fileLength + "%");
}
cn.disconnect();
latch.countDown();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- Java多线程下载文件
- java多线程下载文件
- Java多线程下载文件
- Java多线程下载文件
- Java多线程下载文件
- Java多线程下载文件
- Java 文件多线程下载
- java 多线程下载文件
- Java多线程下载文件
- java多线程下载文件
- Java多线程文件下载
- java多线程下载文件
- JAVA 多线程下载文件
- Java多线程下载文件
- Java 多线程断点下载文件
- Java 多线程断点下载文件
- Java 多线程断点下载文件
- Java 多线程断点下载文件
- 陈学松《深入Linux设备驱动程序内核机制》之MMAP内存页面示例
- zoj1649 BFS
- 杭电 acm 1181 To The Max
- .NET中TextBox控件设置ReadOnly=true后台取不到值三种解决方法
- POJ 4045 Power Station 解题报告
- Java多线程下载文件
- 常用单词
- 异步请求中System.exit(0)注意事项
- android 事件分发
- java中的String,StringBuffer,StringBuild
- beginUpdates和endUpdates---实现UITableView的动画块
- 100米比赛
- vim ctags taglist
- Dialog中使用ON_UPDATE_COMMAND_UI的方法