• java 多线程断点下载demo


    源码链接

      1 import java.io.BufferedReader;
      2 import java.io.File;
      3 import java.io.FileInputStream;
      4 import java.io.InputStream;
      5 import java.io.InputStreamReader;
      6 import java.io.RandomAccessFile;
      7 import java.net.HttpURLConnection;
      8 import java.net.MalformedURLException;
      9 import java.net.URL;
     10 import java.net.URLConnection;
     11 
     12 
     13 public class MutileThreadDownload {
     14     /**
     15      * 线程的数量
     16      */
     17     private static int threadCount = 3;
     18     /**
     19      * 每个下载区块的大小
     20      */
     21     private static long blocksize;
     22     /**
     23      * 正在运行的线程的数量
     24      */
     25     private static int runningThreadCount;
     26     /**
     27      * 
     28      * @param args
     29      * @throws Exception 
     30      */
     31     public static void main(String[] args) throws Exception {
     32         //服务器路径
     33         String path = "http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/chm/JDK_API_1_6_zh_CN.CHM";
     34         URL url = new URL(path);
     35         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
     36         conn.setRequestMethod("GET");
     37         conn.setReadTimeout(5000);
     38         int code = conn.getResponseCode();
     39         if(code == 200) {
     40             long size = conn.getContentLength();//得到服务器端返回的文件的大小
     41             System.out.println("服务器文件的大小:" + size);
     42             blocksize = size / threadCount;
     43             //1.首先在本地创建一个大小跟服务器一模一样的空白文件
     44             File file = new File("temp.CHM");
     45             RandomAccessFile raf = new RandomAccessFile(file, "rw");
     46             raf.setLength(size);
     47             //2.开启若干个子线程分别去下载对应的资源
     48             runningThreadCount = threadCount;
     49             for(int i = 1;i <= threadCount; i++) {
     50                 long startIndex = (i - 1) * blocksize;
     51                 long endIndex = i * blocksize - 1;
     52                 if(i == threadCount) {
     53                     //最后一个线程
     54                     endIndex = size - 1;
     55                 }
     56                 System.out.println("开启线程:" + i + "下载的位置:" + startIndex + "~" + endIndex);
     57                 new DownloadThread(i, startIndex, endIndex, path).start();
     58             }
     59         }
     60         conn.disconnect();
     61     }
     62     
     63     private static class DownloadThread extends Thread {
     64         private int threadId;
     65         private long startIndex;
     66         private long endIndex;
     67         private String path;
     68         
     69         public DownloadThread(int threadId, long startIndex, long endIndex,
     70                 String path) {
     71             super();
     72             this.threadId = threadId;
     73             this.startIndex = startIndex;
     74             this.endIndex = endIndex;
     75             this.path = path;
     76         }
     77         
     78         public void run() {
     79             try {
     80                 //当前线程下载的总大小
     81                 int total = 0;
     82                 File positionFile = new File(threadId + ".txt");
     83                 URL url = new URL(path);
     84                 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
     85                 conn.setRequestMethod("GET");
     86                 //接着从上一次的位置继续下载数据
     87                 if(positionFile.exists() && positionFile.length() > 0) {  //判断是否有记录
     88                     FileInputStream fis = new FileInputStream(positionFile);
     89                     BufferedReader br = new BufferedReader(new InputStreamReader(fis));
     90                     //获取当前线程上次下载的总大小是多少
     91                     String lasttotalstr = br.readLine();
     92                     int lastTotal = Integer.valueOf(lasttotalstr);
     93                     System.out.println("上次线程" + threadId + "下载的总大小:" + lastTotal);
     94                     startIndex += lastTotal;  //加上上次下载的总大小
     95                     fis.close();
     96                 }
     97                 
     98                 conn.setRequestProperty("Range", "bytes=" + startIndex + "-" +endIndex);
     99                 conn.setConnectTimeout(5000);
    100                 int code = conn.getResponseCode();
    101                 System.out.println("code=" + code);
    102                 InputStream is = conn.getInputStream();
    103                 File file = new File("temp.CHM");
    104                 RandomAccessFile raf = new RandomAccessFile(file, "rw");
    105                 raf.seek(startIndex);
    106                 System.out.println("第" + threadId + "个线程:写文件的开始位置:" + String.valueOf(startIndex));
    107                 
    108                 int len = 0;
    109                 byte[] buffer = new byte[1024 * 1024];
    110                 while((len = is.read(buffer)) != -1) {
    111                     RandomAccessFile rf = new RandomAccessFile(positionFile, "rwd");//"rwd"   打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。  
    112                     raf.write(buffer, 0, len);
    113                     total += len;
    114                     rf.write(String.valueOf(total).getBytes());
    115                     rf.close();
    116                 }
    117                 is.close();
    118                 raf.close();
    119                 //conn.disconnect();
    120                 
    121             } catch (Exception e) {
    122                 e.printStackTrace();
    123             }finally {
    124                 //只有所有线程都下载完毕后,才可以删除记录文件
    125                 synchronized (MutileThreadDownload.class) {   //线程安全
    126                     System.out.println("线程" + threadId + "下载完毕了");
    127                     runningThreadCount--;
    128                     if(runningThreadCount < 1) {
    129                         System.out.println("所有线程都工作完毕了。删除临时记录的文件");
    130                         for (int i = 1; i <= threadCount; i++) {
    131                             File f = new File(i + ".txt");
    132                             System.out.println(f.delete());
    133                         }
    134                     }
    135                 }
    136             }
    137         }
    138     }
    139 }
    140  
    #学习笔记,如有谬误,敬请指正。#
  • 相关阅读:
    Xilinx SelectIO资源的使用总结
    Altera usbblaster驱动无法安装的解决办法
    Xilinx FPGA的约束设计和时序分析总结
    OpenMANIPULATORX基本操作
    OpenMANIPULATORX ROS包安装 (Melodic)
    .xacro文件
    open_manipulator OpenCR代码解读
    OpenMANIPULATORX GUI
    ROS建模 urdf
    多机器人Gazebo仿真
  • 原文地址:https://www.cnblogs.com/happyhacking/p/4147588.html
Copyright © 2020-2023  润新知