java實現(xiàn)多線程文件的斷點續(xù)傳
java文件的多線程斷點續(xù)傳大致原理,供大家參考,具體內容如下
談到文件斷點續(xù)傳那么就離不開java.io.RandomAcessFile HttpUrlConnection類
大致思路如下:
1、HttpUrlConnection去請求服務器 獲得文件的長度con.getContentLength()
2、創(chuàng)建一個空的RandomAcessFile來接收,并且指定剛剛獲取的長度setLength
3、開啟N個線程 計算每個線程需要下載的長度
4、獲取之前先去看看下載的進度保存文件是否存在 如果存在就從文件里獲取已經(jīng)下載的進度
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(); ? ? ? ? } ? ? } ? ? /** ? ? ?* 從網(wǎng)絡路徑獲取文件名 ? ? ?* ? ? ?* @param path 網(wǎng)絡路徑 ? ? ?* @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"); // ? ? ? ? ? ? ? ?斷點續(xù)傳 ? ? ? ? ? ? ? ? if (finfo.exists() && finfo.length() > 0) { ? ? ? ? ? ? ? ? ? ? System.out.println(" 斷點續(xù)傳開始"); ? ? ? ? ? ? ? ? ? ? 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()); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
springboot集成RestTemplate及常見的用法說明
這篇文章主要介紹了springboot集成RestTemplate及常見的用法說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Springboot如何同時裝配兩個相同類型數(shù)據(jù)庫
這篇文章主要介紹了Springboot如何同時裝配兩個相同類型數(shù)據(jù)庫,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11