java实现多线程文件的断点续传

java实现多线程文件的断点续传

java文件的多线程断点续传大致原理,供大家参考,具体内容如下

谈到文件断点续传那么就离不开java.io.RandomAcessFile HttpUrlConnection类

大致思路如下:

1、HttpUrlConnection去请求服务器 获得文件的长度con.getContentLength()
2、创建一个空的RandomAcessFile来接收,并且指定刚刚获取的长度setLength
3、开启N个线程 计算每个线程需要下载的长度
4、获取之前先去看看下载的进度保存文件是否存在 如果存在就从文件里获取已经下载的进度
5、开始文件下载
6、临时文件的删除 资源的关闭

下面贴出完整代码

package demo; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; class MultiDownloaFile {     public static final String path = "http://192.168.217.1:8080/androidsimpleserver/HTTP.pdf";     public static final int TOTAL_THREAD_COUNT = 3;     public static int runningThreadCount = 0;     public static void main(String[] args) {         try {             long start = System.currentTimeMillis();             URL url = new URL(path);             HttpURLConnection conn = (HttpURLConnection) url.openConnection();             conn.setRequestMethod("GET");             int code = conn.getResponseCode();             if (code == 200) {                 int length = conn.getContentLength();                 System.out.println("file length:" + length);                 //create  a  null  file  to  save  its  length                 RandomAccessFile raf = new RandomAccessFile(getDownloadFileName(path), "rw");                 raf.setLength(length);                 raf.close();                 //parse  every  thread  that  they  need  how  much  room  to  download                 int blockSize = length / TOTAL_THREAD_COUNT;                 System.out.println("every block size:" + blockSize);                 runningThreadCount = TOTAL_THREAD_COUNT;                 for (int threadId = 0; threadId < TOTAL_THREAD_COUNT; threadId++) {                     int startPosition = threadId * blockSize;                     int endPosition = (threadId + 1) * blockSize - 1;                     if (threadId == (TOTAL_THREAD_COUNT - 1)) {                         endPosition = length - 1;                     }                     System.out.println("thread::" + threadId + " download range:" + startPosition + "~~" + endPosition);                     //start thread  to  download                     new DownloadThread(threadId, startPosition, endPosition).start();                 }             } else {                 System.out.println(" connection  error ");             }         } catch (Exception e) {             e.printStackTrace();         }     }     /**      * 从网络路径获取文件名      *      * @param path 网络路径      * @return 文件名      */     private static String getDownloadFileName(String path) {         return path.substring(path.lastIndexOf("/") + 1);     }     /**      * 下载文件的线程      */     private static class DownloadThread extends Thread {         /**          * 线程id          */         private int threadId;         /**          * 当前线程下载的起始位置          */         private int startPosition;         /**          * 当前线程下载的终止位置          */         private int endPosition;         public DownloadThread(int threadId, int startPosition, int endPosition) {             this.threadId = threadId;             this.startPosition = startPosition;             this.endPosition = endPosition;         }         @Override         public void run() {             System.out.println("thread:" + threadId + " begin working");             // lest thread download it's self range data             try {                 File finfo = new File(TOTAL_THREAD_COUNT + getDownloadFileName(path) + threadId + ".txt"); //                断点续传                 if (finfo.exists() && finfo.length() > 0) {                     System.out.println(" 断点续传开始");                     FileInputStream fis = new FileInputStream(finfo);                     BufferedReader br = new BufferedReader(new InputStreamReader(fis));                     String lastPosition = br.readLine();                     // This thread download data before times;                     int intLastPosition = Integer.parseInt(lastPosition);                     startPosition = intLastPosition;                     fis.close();                 }                 URL url = new URL(path);                 HttpURLConnection conn = (HttpURLConnection) url.openConnection();                 conn.setRequestMethod("GET");                 System.out.println("begin and end:" + threadId + " range of download: " + startPosition + "~~" + endPosition);                 conn.setRequestProperty("Range", "bytes=" + startPosition + "-" + endPosition);                 // Download Resource from server                 int code = conn.getResponseCode();                 if (code == 206) {                     InputStream is = conn.getInputStream(); //                    RandomAccessFile raf = new RandomAccessFile(getDownloadFileName(path), "rw");                     RandomAccessFile raf = new RandomAccessFile(getDownloadFileName(path), "rw");                     // vary important, position of begin to write                     raf.seek(startPosition);                     byte[] buffer = new byte[1024 * 100];                     int len = -1;                     int total = 0; // downloaded data of current thread in this times;                     while ((len = is.read(buffer)) != -1) {                         raf.write(buffer, 0, len);                         // record position of current thread to downloading                         total += len;                         RandomAccessFile inforaf = new RandomAccessFile(TOTAL_THREAD_COUNT + getDownloadFileName(path) + threadId + ".txt", "rwd");                         // save position of current thread                         inforaf.write(String.valueOf(startPosition + total).getBytes());                         inforaf.close();                     }                     is.close();                     raf.close();                     System.out.println("thread:" + threadId + " download complete...");                 } else {                     System.out.println("request download failed.");                 }             } catch (Exception e) {                 e.printStackTrace();             } finally {                 synchronized (MultiDownloaFile.class) {                     runningThreadCount--;                     if (runningThreadCount <= 0) {                         System.out.println("  all  multi thread download complete.   success!!!");                         for (int i = 0; i < TOTAL_THREAD_COUNT; i++) {                             File finfo = new File(TOTAL_THREAD_COUNT + getDownloadFileName(path) + i + ".txt");                             System.out.println(finfo.delete());                         }                     }                 }             }         }     } }

推荐阅读