问题描述
- 多线程加上断点下载多个文件文件出现问题了
-
package cn.com.sinosoft.sfjy.util; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; import java.util.Set; public class DonwloadUtil { public static Map<FileName, DownloadVo> map; public DonwloadUtil(Map<FileName, DownloadVo> map) { DonwloadUtil.map = map; being(); } public void being() { System.out.println("++++++++++++++++++++++++++++++++++++++++++++"); Set<FileName> keySet = map.keySet(); for (FileName fileName : keySet) { map.get(fileName).setFinished(donwload(fileName)); } System.out.println("++++++++++++++++++++++++++++++++++++++++++++"); } public boolean donwload(FileName filename) { // 发送get请求,请求这个地址的资源 try { // 构建请求路径 URL url = new URL(DonwloadUtil.map.get(filename).getDonwloadPath()); // 发送连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 请求方式 conn.setRequestMethod("GET"); // 请求连接超时 conn.setConnectTimeout(5000); // 连接中超时 conn.setReadTimeout(5000); // 请求连接成功 200 if (conn.getResponseCode() == 200) { // 拿到所请求资源文件的长度 long length = conn.getContentLength(); File file = new File(DonwloadUtil.map.get(filename).getTargetPath() + "/" + DonwloadUtil.map.get(filename).getFileName()); // 生成临时文件 RandomAccessFile raf = new RandomAccessFile(file, "rwd"); // 设置临时文件的大小 raf.setLength(length); raf.close(); // 计算出每个线程应该下载多少字节 long size = length / DonwloadUtil.map.get(filename).getThreadCount(); for (int i = 0; i < DonwloadUtil.map.get(filename).getThreadCount(); i++) { // 计算线程下载的开始位置和结束位置 long startIndex = i * size; long endIndex = (i + 1) * size - 1; // 如果是最后一个线程,那么结束位置写死 if (i == DonwloadUtil.map.get(filename).getThreadCount() - 1) { endIndex = length - 1; } System.out.println(filename+"线程" + i + "的下载区间是:" + startIndex + "---" + endIndex); new DownLoadThread(startIndex, endIndex, i, filename).start(); } } return true; } catch (Exception e) { e.printStackTrace(); return false; } } } class DownLoadThread extends Thread { long startIndex; long endIndex; int threadId; FileName filename; public DownLoadThread(long startIndex, long endIndex, int threadId, FileName filename) { super(); this.startIndex = startIndex; this.endIndex = endIndex; this.threadId = threadId; this.filename = filename; } @Override public void run() { try { // 存放当前线程的下载进度文件 File progressFile = new File(filename+""+threadId + ".txt"); // 判断进度临时文件是否存在 if (progressFile.exists()) { FileInputStream fis = new FileInputStream(progressFile); BufferedReader br = new BufferedReader(new InputStreamReader(fis)); // 从进度临时文件中读取出上一次下载的总进度,然后与原本的开始位置相加,得到新的开始位置 startIndex += Integer.parseInt(br.readLine()); fis.close(); } // System.out.println("线程" + threadId + "的下载区间是:" + startIndex + // "---" + endIndex); // 再次发送http请求,下载原文件 HttpURLConnection conn; URL url = new URL(DonwloadUtil.map.get(filename).getDonwloadPath()); // 发送连接 conn = (HttpURLConnection) url.openConnection(); // 请求方式 conn.setRequestMethod("GET"); // 请求连接超时 conn.setConnectTimeout(5000); // 连接中超时 conn.setReadTimeout(5000); // 设置本次http请求所请求的数据的区间 conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex); //System.out.println(filenaem+conn.getResponseCode()); // 请求部分数据,相应码是206 if (conn.getResponseCode() == 206) { // 流里此时只有1/3原文件的数据 InputStream is = conn.getInputStream(); byte[] b = new byte[1024]; int len = 0; int total = 0; // 拿到临时文件的输出流 File file = new File(DonwloadUtil.map.get(filename).getTargetPath() + "/" + DonwloadUtil.map.get(filename).getFileName()); // 生成临时文件 RandomAccessFile raf = new RandomAccessFile(file, "rwd"); // 把文件的写入位置移动至startIndex raf.seek(startIndex); while ((len = is.read(b)) != -1) { // 每次读取流里数据之后,同步把数据写入临时文件 raf.write(b, 0, len); total += len; System.out.println(filename+"线程" + threadId + "下载了" + total); // 生成一个专门用来记录下载进度的临时文件 RandomAccessFile progressRaf = new RandomAccessFile(progressFile, "rwd"); // 每次读取流里数据之后,同步把当前线程下载的总进度写入进度临时文件中 progressRaf.write((total + "").getBytes()); progressRaf.close(); } System.out.println(filename+"线程" + threadId + "下载完毕!"); raf.close(); DonwloadUtil.map.get(filename) .setFinishedThread(DonwloadUtil.map.get(filename).getFinishedThread() + 1); synchronized (DonwloadUtil.map.get(filename).getDonwloadPath()) { if (DonwloadUtil.map.get(filename).getFinishedThread() == DonwloadUtil.map.get(filename) .getThreadCount()) { for (int i = 0; i < DonwloadUtil.map.get(filename).getThreadCount(); i++) { File f = new File(filename+""+i+ ".txt"); f.delete(); } DonwloadUtil.map.get(filename).setFinishedThread(0); } } } } catch (Exception e) { e.printStackTrace(); } } }
解决方案
http://www.cnblogs.com/hoojo/archive/2011/09/30/2196767.html
解决方案二:
多线程断点下载文件
Android多线程断点下载文件
Android多线程实现文件断点下载
时间: 2024-12-21 22:53:10