HttpURLConnection实现多线程下载
来源:互联网 发布:皇室战争恶搞卡牌软件 编辑:程序博客网 时间:2024/05/17 16:54
HttpURLConnection下载
HttpURLConnection下载步骤
1,将要下载的路径封装成一个url对象(一定是可以下载的路径)2,通过url获取conn,并设置conn的各种属性,最重要的是setRequestMethod("GET");3,判断code,如果是200,通过conn获取要下载的文件大小len4,在本地创建一个RandomAccessFile文件,并设置长度 raf.setLength(len);5,定义线程个数threadCount,每个线程要下载的字节大小threadSize,线程的开始下载位置startIndex,结束下载位置endIndex6,for循环,给线程的threadId,线程的开始位置startIndex,endIndex进行赋值,并开启线程7,定义一个MyThread类继承Thread,要放在主类的外面8,定义threadId,startIndex,endIndex,并通过构造方法进行初始化9,将要下载的路径封装成url对象10,设置conn的属性,是重要的是设置请求头属性range ,conn.setRequestProperty("range" , "bytes="+startIndex+"-"+endIndex); 如果range属性设置错误会出现416,作用,设置请求的文件的起始位置11,获取响应码,如果是206,获取输入流12,创建一个RandomAccessFile,并设置raf.seek(startIndex),表示从这个位置开始写出13,将输入流is中的数据放入到内存,raf将内存中的数据写出到文件,并可以设置写出的位置14,关闭输入流is和随机访问流raf注意事项: 1,要下载的路径一定是一个可下载的文件 2,在知道要下载文件大小后,通过raf创建本地文件,一定要设置文件的大小为len 3,在子线程中设置请求头range的时候一定要注意格式,conn.setRequestProperty("range","bytes:"+startIndex+"-"+endIndex);不然会出现416错误 4,在创建raf对象后,一定要设置要写的开始位置 raf.seek(startIndex); 5,下载的时候是请求方式是get,一定不能是Post不然会是411错误
HttpURLConnection断点续传下载步骤
1,在循环往外的写前,定义一个total用来记录从开始到现在写的字节个数2,在循环里面,定义一个线程的当前位置int currentIndex = total + startIndex;3,创建一个随机访问流,并设置模式为"rwd",直接写入硬盘4,在设置请求头range前,创建一个bufferedReader,读取文件里面的数据,并将数据转换为int类型5,然后将startIndex = 读取的结果注意事项: 要使用RandomAccessFile(file,"rwd")来写,不然写出的文件内容为0,这样读取的时候字符串转换为数据就为异常
HttpURLConnection断点续传完善
问题,每次下载完,.txt文件也写完了,如果不删除,下次下载的时候直接下载完成了解决方案: 1,在每个线程下载完之后,就将该.txt文件删除 2,删除如果删不掉,因为没有写完之后,没有关raf的流
package com.heima.download;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileOutputStream;import java.io.FileReader;import java.io.FileWriter;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;public class Download { public static void main(String[] args) { /* * * 从服务器上下载的步骤,上传需要使用AsncHttpClient 但是下载,的话不需要 下载步骤 1,将请求的路径封装成一个Url路径对象 * 2,通过url获取流is 3,通过is获取文件的大小 * 4,在本地使用RandomAcessFile创建一个大文件,并设置大小跟服务器上一样大 * 5,定义线程个数threadCount,每个线程要下载的大小threadSize,线程的起始位置startIndex 线程的结束位置 * endIndex 6,使用for循环初始化线程的id,threadId,startIndex,endIndex,创建线程并开启 * 线程的结束位置,如果是最后一个线程endIndex = len - 1; * * 7,在类中创建一个内部类MyThread继承Thread 8,创建一个构造方法,初始化threadId,startIndex * ,endIndex 9,将要下载的请求路径封装成Url对象,并获取流对象 * 10,设置流的conn.setRequestProperty("Range" * ,"bytes="+startIndex+"-"+endIndex); 11,判断响应码,如果是206的话 * 12,将读入到的流使用RandomAccessFile raf进行写出 */ try { // 1,将请求的下载路径封装成一个url对象// URL url = new URL("http://localhost:8080/itheima74/feiq.exe"); URL url = new URL("http://img1.3lian.com/2015/w2/60/d/41.jpg"); // 获取httpurlconnection连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置连接属性 conn.setRequestMethod("GET"); conn.setReadTimeout(5000); conn.setConnectTimeout(5000); int code = conn.getResponseCode(); System.out.println(code); if (code == 200) { // 通过连接获取要下载的文件大小 int len = conn.getContentLength(); // 在本地创建一个大小一样的RandomAccessFile文件,格式也要一样// RandomAccessFile raf = new RandomAccessFile(// new File("fuck.exe"), "rw"); RandomAccessFile raf = new RandomAccessFile( new File("fuck.jpg"), "rw"); //一定要文件的大小 raf.setLength(len); // 定义线程的个数threadCount,每个线程的要下载的大小 threadSize,线程的起始位置startIndex // 结束位置endIndex int threadCount = 3; int startIndex; int endIndex; int threadSize = len / threadCount; for (int threadId = 0; threadId < threadCount; threadId++) { startIndex = threadId * threadSize; endIndex = (threadId + 1) * threadSize - 1; if (threadId == threadCount - 1) { endIndex = len - 1; } System.out.println(threadId); new MyThread(threadId, startIndex, endIndex).start(); } } } catch (Exception e) { } }}class MyThread extends Thread { int threadId; int startIndex; int endIndex; // 通过构造方法给线程的id,线程的开始位置,线程的结束位置进行初始化 MyThread(int threadId, int startIndex, int endIndex) { this.threadId = threadId; this.startIndex = startIndex; this.endIndex = endIndex; } @Override public void run() { // 将要下载的路径封装成一个URL对象 try {// URL url = new URL("http://localhost:8080/itheima74/feiq.exe"); URL url = new URL("http://img1.3lian.com/2015/w2/60/d/41.jpg"); // 通过url获取连接对象 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置连接对象的属性 conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); File file = new File(threadId+".txt"); if(file.exists()){ BufferedReader br = new BufferedReader(new FileReader(file)); startIndex = Integer.parseInt(br.readLine()); br.close(); } System.out.println("线程"+threadId+"从"+startIndex+"开始下载"); //一定要记住要从某个位置到另一个位置下载,一定要设置请求头Range conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); int code = conn.getResponseCode(); //部分请求的响应码为206 if(code == 206){ //获取响应的字节输入流 System.out.println("线程"+threadId+"开始下载"); InputStream is = conn.getInputStream();// RandomAccessFile raf = new RandomAccessFile(new File("fuck.exe"), "rw"); RandomAccessFile raf = new RandomAccessFile(new File("fuck.jpg"), "rw");// 设置随机访问流开始写的位置 raf.seek(startIndex); int len = -1; //有效的字节码长度 byte[] buffer = new byte[1024*10];//定义一个小数组进行读入 int total = 0; while((len = is.read(buffer)) != -1){ raf.write(buffer, 0, len); total = total + len; int currentIndex = total + startIndex; //将当前读入的字节数写出到本地文件 RandomAccessFile raf1 = new RandomAccessFile(new File(threadId+".txt"), "rwd"); raf1.write((currentIndex+"").getBytes()); raf1.close(); } //关闭读入和字节流和写出的随机文件访问流 is.close(); raf.close(); System.out.println("线程"+threadId+"下载结束"); File file1 = new File(threadId+".txt"); file1.delete(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
0 0
- HttpURLConnection实现多线程下载
- 使用HttpURLConnection实现多线程下载
- android HttpURLConnection实现多线程下载
- HttpURLConnection实现多线程网络下载
- HttpUrlConnection实现多线程下载网络资源
- Android 使用HttpURLConnection实现多线程下载 笔记
- android中使用HttpURLConnection实现多线程下载
- HttpURLConnection实现多线程下载资源contentLength()
- Android-使用HttpURLConnection实现多线程下载
- Java使用HttpUrlConnection实现多线程断点下载
- 使用greenDao+HttpurlConnection实现多线程断点下载
- HttpURLConnection多线程下载
- HttpURLConnection多线程下载
- Java HttpUrlConnection多线程下载
- Android HttpURLConnection 多线程下载
- android多线程下载-HttpURLConnection
- 多线程下载httpurlConnection
- Android开发_使用HttpURLConnection实现多线程下载
- 神经网络使用情景
- String.CopyTo
- 1077. Kuchiguse (20)解题报告
- Android关于Theme.AppCompat相关问题的深入分析
- 139. Word Break
- HttpURLConnection实现多线程下载
- int转 string
- 数据库学习笔记和小练习(6)sql查询和更新练习
- 面试专栏:算法与数据结构,虚拟机,Java基础,JavaWeb
- Swift 3.0 API设计准则
- EventBus 解析
- 在 CentOS7 上安装 zookeeper-3.4.9 服务
- JSP新闻系统之六 后台登陆页面
- 一个rm -rf ???*命令下去, 整个人都不好了