java(android)多线程下载,和多线程断点下载
2015-06-07 21:12
351 查看
多线程(断点)下载要点:
1:计算出每个线程要下载的大小 ,下载的起始位置和结束位置
2:设置请求头,请求服务器下载文件的哪部分 conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
3:创建一个与服务器大小一样的随机读写文件 RandomAccessFile file = new RandomAccessFile("文件名", "rw");
(断点)
4:每读写一段数据记录一次下载位置
5:重新开始下载时,要从保存的配置文件中读取下载位置
一:多线程下载Demo
1:计算出每个线程要下载的大小 ,下载的起始位置和结束位置
2:设置请求头,请求服务器下载文件的哪部分 conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
3:创建一个与服务器大小一样的随机读写文件 RandomAccessFile file = new RandomAccessFile("文件名", "rw");
(断点)
4:每读写一段数据记录一次下载位置
5:重新开始下载时,要从保存的配置文件中读取下载位置
一:多线程下载Demo
import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; /** * 多线程下载 */ public class MultiTheadDownload { // 开启的线程数,默认是3个线程啊。 private static int theandCount = 3; public static void main(String[] args) throws Exception { String path = "http://10.0.177.167:8080/360.exe";// 访问网址 URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(5000); conn.setRequestMethod("GET"); int code = conn.getResponseCode(); if (code == 200) { // 得到文件的大小 int length = conn.getContentLength(); // 计算出每个线程要下载的大小。后面不能整除的留给最后一个线程。 int blockSize = length / theandCount; // System.out.println(); // 创建一个与服务器大小一样的随机读写文件 RandomAccessFile file = new RandomAccessFile("360.exe", "rw"); file.setLength(length);// 设置生成的随机文件的大小 file.close(); for (int theandId = 1; theandId <= theandCount; theandId++) { // 求出线程开始下载的位置 :(线程号-1)*每个线程下载的大小。 int startIndex = (theandId - 1) * blockSize; // 求出线程结束下载的位置: 线程号*每个线程下载的大小-1 int endIndex = theandId * blockSize - 1; if (theandId == theandCount) { endIndex = length; } System.out.println("线程" + theandId + "下载" + startIndex + "---->" + endIndex); // 开启线程 new DownloadTheand(startIndex, endIndex, theandId, path).start(); } } else { System.out.println("连接失败"); } } /** * 每个线程处理类 */ public static class DownloadTheand extends Thread { private int startIndex;// 文件的开始位置 private int endIndex;// 文件的结束位置 private String path;// 下载URL private int threadId;// 线程id /** * * @param startIndex * 文件的开始位置 * @param endIndex * 文件的结束位置 * @param filePath * 下载URL */ public DownloadTheand(int startIndex, int endIndex, int threadId, String path) { this.startIndex = startIndex; this.endIndex = endIndex; this.path = path; this.threadId = threadId; } public void run() { try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(5000); conn.setRequestMethod("GET"); // 设置请求头,请求服务器下载文件的哪部分 conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex); // 从服务器返回全部资源200 ok,如果从服务器请求部分资源 206 ok int code = conn.getResponseCode(); System.out.println(code); InputStream in = conn.getInputStream();// 返回从startIndex开始的部分文件的流 // 开启随机文件读取流 RandomAccessFile raf = new RandomAccessFile("360.exe", "rw"); raf.seek(startIndex);// 设置随机文件从哪里开启读写 int len = 0; byte[] buffe = new byte[1024]; while ((len = in.read(buffe)) != -1) { raf.write(buffe, 0, len); } in.close(); raf.close(); System.out.println("当前线程" + threadId + "下载完成"); } catch (Exception e) { e.printStackTrace(); System.out.println("当前线程" + threadId + "下载成败"); } } } }二;多线程断点下载Demo
import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; /** * 多线程断点下载 */ public class MultiTheadBreakpointDownload { /**开启的线程总数**/ public static int threadCount = 3; /**正在运行的线程数**/ public static int runningThread = 3; public static void main(String[] args) throws Exception { // 1.连接服务器 , 获取一个文件, 获取文件的长度, 在本地创建一个大小跟服务器文件一样大的临时文件 String path = "http://10.0.177.167:8080/360.exe"; URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); int code = conn.getResponseCode(); if (code == 200) { // 服务器返回的数据的长度 实际上就是文件的长度 int length = conn.getContentLength(); System.out.println("文件总长度:" + length); // 在客户端本地 创建出来一个大小跟服务器端文件一样大小的临时文件 RandomAccessFile raf = new RandomAccessFile("setup.exe", "rw"); // 指定创建的这个文件的长度 raf.setLength(length); raf.close(); // 假设是3个线程去下载资源. // 平均每一个线程下载的文件的大小. int blockSize = length / threadCount; for (int threadId = 1; threadId <= threadCount; threadId++) { // 第一个线程下载的开始位置 int startIndex = (threadId - 1) * blockSize; int endIndex = threadId * blockSize - 1; if (threadId == threadCount) {// 最后一个线程 下载的长度 要稍微长一点 endIndex = length; } System.out.println("线程:" + threadId + "下载:---" + startIndex + "--->" + endIndex); new DownloadThread(path, threadId, startIndex, endIndex).start(); } } else { System.out.println("服务器错误."); } } /** * 下载文件的子线程 每一个线程 下载对应位置的文件 * * @author Administrator * */ public static class DownloadThread extends Thread { private int threadId;//线程id private int startIndex;//线程下载的开始位置 private int endIndex;// 线程下载的结束位置. private String path;//下载URL /** * @param path * 下载URL * @param threadId * 线程id * @param startIndex * 线程下载的开始位置 * @param endIndex * 线程下载的结束位置. */ public DownloadThread(String path, int threadId, int startIndex, int endIndex) { this.threadId = threadId; this.startIndex = startIndex; this.endIndex = endIndex; this.path = path; } @Override public void run() { try { // 检查是否存在 记录下载长度的文件 ,如果存在读取这个文件的数据. File tempFile = new File(threadId + ".txt"); if (tempFile.exists() && tempFile.length() > 0) { FileInputStream fis = new FileInputStream(tempFile); byte[] temp = new byte[1024]; int leng = fis.read(temp); String downloadLen = new String(temp, 0, leng); int downloadlenInt = Integer.parseInt(downloadLen); startIndex = downloadlenInt;// 修改下载的真实的开始位置. fis.close(); } URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); // 重要: 请求服务器下载部分的文件 指定文件的位置. conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex); System.out.println("线程真实下载:" + threadId + "下载:---" + startIndex + "--->" + endIndex); conn.setConnectTimeout(5000); int code = conn.getResponseCode(); // 从服务器请求全部资源 200 ok // 如果从服务器请求部分资源 206 ok if (code == 206) { InputStream is = conn.getInputStream();// 已经设置了 请求的位置 RandomAccessFile raf = new RandomAccessFile("setup.exe", "rw"); // 随机写文件的时候 从哪个位置开始写 raf.seek(startIndex);// 定位文件 int len = 0; byte[] buffer = new byte[1024]; int total = 0;// 已经下载的数据长度 while ((len = is.read(buffer)) != -1) { RandomAccessFile file = new RandomAccessFile(threadId + ".txt", "rw");// 作用:记录当前线程下载的数据长度 raf.write(buffer, 0, len); total += len; // System.out.println("线程:" + threadId + "total:" + // total); file.write((total + startIndex + "").getBytes());// 记录的是下载位置. file.close(); } is.close(); raf.close(); System.out.println("线程:" + threadId + "下载完毕了..."); } else { System.out.println("线程:" + threadId + "下载失败..."); } File deleteFile = new File(threadId + ".txt"); deleteFile.delete();// 当线程下载完毕后 清楚掉 下载的记录 // 如何去判断应用程序已经下载完毕. } catch (Exception e) { e.printStackTrace(); } finally { runningThread--; if (runningThread == 0) {// 所有的线程 已经执行完毕了. for (int i = 1; i <= 3; i++) { File file = new File(i + ".txt"); file.delete(); } System.out.println("文件下载完毕 ,删除所有的下载记录."); } } } } }
相关文章推荐
- Android应用防止截屏
- java用正则表达式判断字符串中是否仅包含英文字母、数字和汉字 分类: Android JAVA 2015-06-07 21:08 31人阅读 评论(0) 收藏
- android 判断字符串是否为数字或中文或字母
- android 判断字符串是否为数字或中文或字母 分类: Android JAVA 2015-06-07 21:07 29人阅读 评论(0) 收藏
- Android的DrawText详解
- Android 绘图和shape圆形
- Developing for Android V: The Rules: Language and Libraries
- android实现边框圆角
- Android内核开发:图解Android系统的启动过程
- Android内核开发:图解Android系统的启动过程
- Android应用AsyncTask处理机制详解及源码分析
- Android Bitmap回收 注意事项
- Android应用层View绘制流程与源码分析
- android学习笔记(一)activity的基本用法和创建,bundle如何传递数据,intent的用法
- Android提权漏洞分析——rageagainstthecage
- Android 优化电池使用时间——确定和监控基座对接状态和类型
- android中解析doc、docx、xls、xlsx格式文件
- Android中ListView.getCount()与ListView.getChildCount()区别
- android实现MP3播放器
- Android开发资源获取国内代理(转载)