Java_多线程_断点_下载
2016-06-29 18:41
375 查看
代码组成:
1.核心代码是通过GET请求获取数据;
2.用RandomAccessFile 创建 与获取的数据长度相同的 文件,该类可以指定数据写入文件的位置;
3.
该方法可以设置 获取总数据中的 部分数据,注意:获取部分数据时,网络连接状态码是:206 (SC_PARTIAL_CONTENT)
//206 (SC_PARTIAL_CONTENT)是在服务器完成了一个包含Range头信息的局部请求时被发送的。
4.关键字 synchronized 解决多线程中同步问题
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
1.核心代码是通过GET请求获取数据;
2.用RandomAccessFile 创建 与获取的数据长度相同的 文件,该类可以指定数据写入文件的位置;
3.
conn.setRequestProperty("range", "bytes=" + startIndex + "-" + endIndex);
该方法可以设置 获取总数据中的 部分数据,注意:获取部分数据时,网络连接状态码是:206 (SC_PARTIAL_CONTENT)
//206 (SC_PARTIAL_CONTENT)是在服务器完成了一个包含Range头信息的局部请求时被发送的。
4.关键字 synchronized 解决多线程中同步问题
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
public class Down_BreakPoint { //数据的长度 static int lenght; //线程的个数 static int threadCount = 3; //正在运行线程的格式 static int currentRunningThread = threadCount; //数据的地址 static String path = "http://ossweb-img.qq.com/images/gameshop/dnf/1.jpg"; public static void main(String[] args) { //数据的开始和结束位置 int startIndex,endIndex; try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); if(conn.getResponseCode() == 200) { lenght = conn.getContentLength(); //获取数据长度 File file = new File(getFileName(path)); //创建文件 RandomAccessFile raf = new RandomAccessFile(file, "rw"); raf.setLength(lenght); //设置(空)文件大小 raf.close(); //设置每个线程所获得数据的开始和结束位置 in a727 t blockSize = lenght/threadCount; for(int threadId = 0; threadId < threadCount; threadId++ ) { startIndex = threadId * blockSize; endIndex = (threadId+1) * blockSize -1; if(threadId == threadCount - 1){ endIndex = lenght -1; } System.out.println("start: " + startIndex + " ; end: " + endIndex); //创建(下载)线程 DownloadFilePartThread thread = new DownloadFilePartThread(threadId, startIndex, endIndex); thread.start(); } } } catch (Exception e) { e.printStackTrace(); } } public static class DownloadFilePartThread extends Thread { private int startIndex; private int threadId; private int endIndex; private File config; private String index; //记录线程当前写入数据开始位置 public DownloadFilePartThread(int threadId, int startIndex, int endIndex) { this.threadId = threadId; this.startIndex = startIndex; this.endIndex = endIndex; index = startIndex + ""; config(); //初始化线程当前写入数据开始位置 } private void config() { config = new File(threadId + ""); if(config.exists() && config.length()>0){ BufferedReader br; try { br = new BufferedReader(new FileReader(config)); index = br.readLine(); startIndex = Integer.parseInt(index); br.close(); } catch (Exception e) { e.printStackTrace(); } } } public void run() { super.run(); try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); //设置接受属性--接收范围 conn.setRequestProperty("range", "bytes=" + startIndex + "-" + endIndex); if(conn.getResponseCode() == 206) { //接收部分数据时,状态码为:206 InputStream is = conn.getInputStream(); File file = new File(getFileName(path)); RandomAccessFile raf = new RandomAccessFile(file, "rw"); //设置 开始写入的位置 raf.seek(startIndex); int len = 0; byte[] buffer = new byte[1024]; while((len = is.read(buffer))>0) { raf.write(buffer, 0, len); OutputStream os = new FileOutputStream(config); index = Integer.parseInt(index) + len + ""; os.write(index.getBytes()); //写入配置文件当前写入数据的位置 os.close(); } System.out.println("threadId: " + threadId + "Finish" ); is.close(); raf.close(); synchronized (Down_BreakPoint.class) { //解决线程安全问题 //删除配置文件 currentRunningThread--; if(currentRunningThread == 0) { File ff ; for(int i = 0; i<threadCount ;i++){ ff = new File(i+""); ff.delete(); } } } } } catch (Exception e) { e.printStackTrace(); } } } public static String getFileName(String path) { int index = path.lastIndexOf("/"); return path.substring(index + 1); } }
相关文章推荐
- 向Eclipse Java Mars导入项目
- JavaSE 基础 第38节 接口的实现
- JAVA虚拟机内置锁机制的升级流程
- Java中构造方法、类方法、final方法的重载与覆盖问题
- MAC JDK版本切换
- 在ubuntu下安装配置jdk
- java构造者模式的使用
- java 程序打包+运行
- java匿名类
- java处理SQL特殊字符转义 防止sql注入
- JavaSE 基础 第37节 接口概述
- LinkedList源码解析
- 第三章 Java基本的程序设计结构---笔记
- Java_语言基础:前置自增和后置自增
- 带下拉列表的输入框
- java 算法-基数排序
- Java 之 SimpleDateFormat
- H2Database之h2-xxx.jar分析
- java中的线程池
- Intellij Idea 将java项目打包成jar