你的位置:首页 > 操作系统

[操作系统]多线程下载和断点续传技术的实现原理。


package com.zzw.constant;public class Contant {  public static int threadCount = 3;} 1 package com.zzw.download; 2  3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 import java.io.InputStream; 9 import java.io.InputStreamReader; 10 import java.io.RandomAccessFile; 11 import java.net.HttpURLConnection; 12 import java.net.MalformedURLException; 13 import java.net.URL; 14 import java.net.URLConnection; 15 16 import javax.tools.FileObject; 17 18 import com.zzw.constant.Contant; 19 20 public class TestDownload 21 { 22   //public static int threadCount = 3; 23   public static int blockSize = 0; 24 25   public static void main(String[] args) throws Exception 26   { 27     URL url = new URL("http://localhost:8080/download/cc.zip"); 28     29     HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 30     conn.setRequestMethod("GET"); 31     conn.setReadTimeout(10000); 32     33     long length = conn.getContentLength(); 34     35     conn.connect(); //连接 36     File file = new File("cc.zip"); 37     38     RandomAccessFile randomFile = new RandomAccessFile(file,"rwd"); 39     randomFile.setLength(length); 40     41     //每一个线程他需要下载的大小 42     System.out.println("总大小:" + length); 43     blockSize = (int) (length / Contant.threadCount); 44     System.out.println("每一个线程下载的大小:" + blockSize); 45     long start = 1; 46     long end = 0; 47     for(int i=1; i < (Contant.threadCount+1); i++) 48     { 49       50       //1 >> 0 - 46354938 123456 51       //2 >> 46354939 -(46354939 + 46354938) 52       //3 >>  53       start = blockSize * (i -1); 54       end = blockSize*i -1; 55       if(i == Contant.threadCount) 56       { 57         end = length; 58       } 59       System.out.println("第" + i + "个线程下载的区间:" + start + " - " + end); 60       new downloadThread(file, i, start, end).start(); 61     } 62     63     conn.disconnect(); 64   } 65 } 66 67 class downloadThread extends Thread 68 { 69   private File path; //本地磁盘的地址 70   private String url = "http://localhost:8080/download/cc.zip" ; //HTTP请求的地址 71   private Integer threadID; //当前是第几个线程 72   private long start; //该线程下载的起始位置 73   private long end; //该线程的结束位置 74   75   public downloadThread(File path, Integer threadID, long start, 76       long end) { 77     this.path = path; 78     this.threadID = threadID; 79     this.start = start; 80     this.end = end; 81     82   } 83 84   @Override 85   public void run() 86   { 87     try { 88       System.out.println(threadID + "开启读取"); 89       File contextFile = new File(threadID +".txt"); 90       if(!contextFile.exists()) 91       { 92         contextFile.createNewFile(); 93       } 94       95       //读取断线信息里面的数据来重新的指定从哪里开始写 96       BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(contextFile))); 97       String info = reader.readLine(); 98       if(null != info && info.length() > 0) 99       {100         start = start + Integer.parseInt(info);101       }102       103       System.out.println("start........=" + start);104       URL uri = new URL(url);105       HttpURLConnection conn = (HttpURLConnection) uri.openConnection();106       conn.setRequestProperty("Range", "bytes="+start +"-" + end);107       conn.setReadTimeout(50000);108       conn.setConnectTimeout(50000);109       110       conn.connect();111       112       //让http请求只请求一个片段113       System.out.println("bytes="+start +"-" + end);114       115       //判断一下是否为200?116       int status = conn.getResponseCode();117       118       if(status / 100 == 2)119       {120         int total = 0; //总共下载的字节数121         //FileOutputStream out = new FileOutputStream(new File(threadID +".txt")); 不靠谱了122         RandomAccessFile random = new RandomAccessFile(path, "rw");123         124         random.seek(start);125         InputStream in = conn.getInputStream();126         byte[] buffer = new byte[1024];127         int len = 0;128         129         while((len = in.read(buffer)) != -1)130         {131           RandomAccessFile duandian = new RandomAccessFile(contextFile, "rwd");132           random.write(buffer, 0, len);133           total += len;134           duandian.write(String.valueOf(total).getBytes());135           duandian.close();136         }137         in.close();138         random.close();139       }140       conn.disconnect();141       System.out.println(threadID + "读取完成");142     } catch (MalformedURLException e) {143       e.printStackTrace();144     } catch (IOException e) {145       e.printStackTrace();146     }finally147     {148       synchronized (TestDownload.class)149       {150         Contant.threadCount --;151         System.out.println("Contant.threadCount = " + Contant.threadCount);152         if(Contant.threadCount == 0)153         {154           for(int i=1; i < 4; i++)155           {156             File contextFile = new File(i +".txt");157             System.out.println(contextFile.delete() +"  ccc");158           }159         }160       }161     }162     163   }164 }