JAVA實現多線程下載
阿新 • • 發佈:2019-04-06
access target 創建 tle exce 文件名 技術分享 trace any
1.開啟三個下載線程;
2.開啟一個監視線程,用於查看下載進度。
完整代碼
import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; public class JavaMultiThreadDown { public static void main(String[] args) throws Exception { // 下載路徑使用的是百度網盤上文件的下載路徑 String _下載路徑 = "https://bjbgp01.baidupcs.com/file/1d9cedae59e9042a85cb0b98b4340c9c?bkt=p3-00007b4ef6ea09a0f17a89712f670b4985c6&fid=3255250463-250528-363978972781448&time=1554510897&sign=FDTAXGERQBHSKfW-DCb740ccc5511e5e8fedcff06b081203-1Sm5YGIZMjBwhUyJY4n2UBJLkJ0%3D&to=75&size=5528379&sta_dx=5528379&sta_cs=0&sta_ft=pdf&sta_ct=0&sta_mt=0&fm2=MH%2CQingdao%2CAnywhere%2C%2Chubei%2Cpbs&ctime=1554510826&mtime=1554510826&resv0=cdnback&resv1=0&vuk=3255250463&iv=2&htype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=00007b4ef6ea09a0f17a89712f670b4985c6&expires=8h&rt=sh&r=458234945&mlogid=2211612084113124362&vbdid=1929586120&fin=%E4%B8%8B%E8%BD%BD%E6%B5%8B%E8%AF%95.pdf&fn=%E4%B8%8B%E8%BD%BD%E6%B5%8B%E8%AF%95.pdf&rtype=1&dp-logid=2211612084113124362&dp-callid=0.1.1&hps=1&tsl=0&csl=0&csign=4j3EXxSQdY9W8SenN6CIXXqjvfE%3D&so=0&ut=1&uter=4&serv=0&uc=4192912830&ti=90e00819b6f54250603b4062c17fc35df0cc8c47b8fc9467&by=themis"; String _本地文件 = "有那種網站嘛?有,還是合集哦.pdf"; int _線程數量 = 3; // 初始化DownUtil對象 final Downloader downLoader = new Downloader(_下載路徑, _本地文件, _線程數量); // 開始下載 downLoader.download(); } } class Downloader { private String netUrl;// 下載資源的路徑 private String saveFile;// 下載的路徑(含文件名) private int threadNum;// 線程數量 private DownLoaderThread[] threads;// 線程數組 private int fileSize;// 下載的文件的Size public Downloader(String netUrl, String targetFile, int threadNum) { this.netUrl = netUrl; this.saveFile = targetFile; this.threadNum = threadNum; // 初始化線程數組 this.threads = new DownLoaderThread[threadNum]; } public void download() throws Exception { URL url = new URL(netUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5 * 1000); conn.setRequestMethod("GET"); fileSize = conn.getContentLength(); System.out.println("待下載文件的大小為:" + (double) (fileSize / 1024) / 1024 + "M"); conn.disconnect(); // 分部下載 int currentPartSize = fileSize / threadNum + 1; RandomAccessFile file = new RandomAccessFile(saveFile, "rw"); // 設置本地文件大小 file.setLength(fileSize); file.close(); // 開啟下載線程 for (int i = 0; i < threadNum; i++) { // 計算每條線程的下載的開始位置 int startPos = i * currentPartSize; // 每個線程使用一個RandomAccessFile進行下載 RandomAccessFile currentPart = new RandomAccessFile(saveFile, "rw"); // 定位線程的下載位置 currentPart.seek(startPos); // 創建下載線程 threads[i] = new DownLoaderThread(startPos, currentPartSize, currentPart); // 啟動下載線程 threads[i].start(); } Thread overseer = new Thread(new Overseer(this)); overseer.start(); } private class DownLoaderThread extends Thread { private int startPos;// 當前線程的下載位置 private int currentPartSize;// 當前線程負責下載的文件大小 private RandomAccessFile currentPart;// 當前線程需要下載的文件塊 public int length;// 該線程已下載的字節數 public DownLoaderThread(int startPos, int currentPartSize, RandomAccessFile currentPart) { this.startPos = startPos; this.currentPartSize = currentPartSize; this.currentPart = currentPart; } @Override public void run() { try { URL url = new URL(netUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5 * 1000); conn.setRequestMethod("GET"); InputStream inStream = conn.getInputStream(); // 跳過不需要下載的部分 inStream.skip(this.startPos); byte[] buffer = new byte[1024]; int hasRead = 0; // 讀取網絡數據,並寫入本地文件 while (length < currentPartSize && (hasRead = inStream.read(buffer)) != -1) { currentPart.write(buffer, 0, hasRead); // 累計該線程下載的總大小 length += hasRead; } currentPart.close(); inStream.close(); } catch (Exception e) { e.printStackTrace(); } } } private class Overseer implements Runnable { Downloader downLoader; Overseer(Downloader downLoader) { this.downLoader = downLoader; } @Override public void run() { double p; while ((p = getCompleteRate()) < 100) { // 隔段時間查詢一次任務完成進度, System.out.println("已完成:" + p + "%"); try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("下載完畢"); } // 獲取下載的完成百分比 private double getCompleteRate() { // 統計多條線程已經下載的總大小 int sumSize = 0; for (int i = 0; i < threadNum; i++) { sumSize += threads[i].length; } // 返回已經完成的百分比 int percent = (int) (sumSize * 100.0 / fileSize); return percent; } } }
運行結果
待下載文件的大小為:5.271484375M
已完成:0.0%
已完成:3.0%
已完成:13.0%
已完成:21.0%
已完成:29.0%
已完成:33.0%
已完成:35.0%
已完成:50.0%
已完成:64.0%
已完成:66.0%
已完成:66.0%
已完成:66.0%
已完成:66.0%
已完成:66.0%
已完成:73.0%
已完成:90.0%
下載完畢
JAVA實現多線程下載