实现多线程下载同一个文件
2016-03-18 19:01
597 查看
原理:
示例代码:
public class LoadFile { private static int threadCount = 3;// 下载的线程数量 public static void main(String[] args) { // 1、与服务器建立连接,获得文件的大小,在本地创建一个与需下载文件同等大小的临时文件 String path = "http://localhost/safe.exe"; try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); int code = conn.getResponseCode(); if(200 == code) { // 获得文件的长度 int length = conn.getContentLength(); System.out.println("文件总长度为:"+length); // 在本地创建一个可以随机读取的与源文件同等大小的临时文件 RandomAccessFile raf = new RandomAccessFile("safe.exe", "rwd"); // 指定文件的长度 raf.setLength(length);// 设置文件长度 raf.close(); // 2、实现多线程下载资源 int blockSize = length / threadCount ;// 每个线程平均需要下载文件的大小 for(int threadId = 1; threadId <= threadCount; threadId++) { // 每个线程下载文件的初始位置和结束位置 int startIndex = (threadId-1) * blockSize; int endIndex = threadId * blockSize - 1; // 下载的最后一块的情况 if(threadCount == threadId) { endIndex = length - 1;// 如果不减1的话,就超出了文件的范围 } System.out.println("线程 "+threadId+"下载位置为:"+startIndex+"--->"+endIndex); // 启动下载线程 new DownloadThread(path, startIndex, endIndex, threadId).start(); } } else { System.out.println("服务器出现错误"); } } catch (Exception e) { System.out.println("连接服务器URL出现错误"); e.printStackTrace(); } } }
public class DownloadThread extends Thread { private String path;// 服务器路径 private int startIndex;// 块文件开始位置 private int endIndex;// 快文件结束位置 private int threadId;// 线程编号 public DownloadThread() { } public DownloadThread(String path, int startIndex, int endIndex, int threadId) { this.path = path; this.startIndex = startIndex; this.endIndex = endIndex; this.threadId = threadId; } @Override public void run() { try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); // 提交请求可以从指定位置读取文件 conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex); int code = conn.getResponseCode(); // 请求全部文件成功返回200, 请求部分文件成功返回206 if (206 == code) { RandomAccessFile raf = new RandomAccessFile("safe.exe", "rwd"); // 随机文件从哪里读 raf.seek(startIndex);// 定位文件 InputStream is = conn.getInputStream(); int len = 0; byte[] buffer = new byte[1024]; while ((len = is.read(buffer)) != -1) { raf.write(buffer, 0, len); } is.close(); raf.close(); System.out.println("线程" + threadId + "下载完毕!!!!"); } else { System.out.println("线程"+threadId+"请求的部分资源失败"); } } catch (Exception e) { System.out.println("下载线程的URL连接异常"); e.printStackTrace(); } } }
// 别下载太大的文件,可能等待时间很长 /*Output: 文件总长度为:11556608 线程 1下载位置为:0--->3852201 线程 2下载位置为:3852202--->7704403 线程 3下载位置为:7704404--->11556607 线程2下载完毕!!!! 线程1下载完毕!!!! 线程3下载完毕!!!! */
相关文章推荐
- root用户更改密码
- 培养下属的12条黄金原则!
- VMware vSphere 6.0 升级已知问题
- myloader还原恢复详解
- 在mt7628实现alsa架构解码并播放音频文件
- 4个你需要知道的Asset Catalog的秘密
- 简述操作系统
- bug_ _ android.view.WindowManager$BadTokenException: Unable to add window -- token
- ps
- 求自然数幂和的各种方法(还有坑)
- LightOJ 1032 Fast Bit Calculations
- jQuery动画效果
- 对i++,i--,++i,--i的易解,在此举一例子详解
- haproxy para config
- JAVA日志
- MySQL系列:MySQL关系型数据库架构
- C#代码分析
- 课本笔记
- Android 的画布Canvas和画笔Paint
- Python在windows下安装模块出现编译错误解决方法