標籤:ace 一個 let range xtend download eth 靜態變數 刪除
import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;import javax.print.attribute.standard.Finishings;public class MultiDownload { static int ThreadCount = 3; //代表3個進程 static int finishedThread = 0; //記錄檔案下完的數字 //確定 static String path = "http://192.168.13.13:8080/QQPlayer.exe"; public static void main(String[] args) { //發送get請求,請求這個地址的資源 try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); if(conn.getResponseCode() == 200){ //拿到所請求資源檔的長度 int length = conn.getContentLength(); File file = new File("QQPlayer.exe"); //產生臨時檔案 RandomAccessFile raf = new RandomAccessFile(file, "rwd"); //設定臨時檔案的大小 raf.setLength(length); raf.close(); //計算出每個線程應該下載多少位元組 int size = length / ThreadCount; for (int i = 0; i < ThreadCount; i++) { //計算線程下載的開始位置和結束位置 int startIndex = i * size; int endIndex = (i + 1) * size - 1; //如果是最後一個線程,那麼結束位置寫死 if(i == ThreadCount - 1){ endIndex = length - 1; }// System.out.println("線程" + i + "的下載區間是:" + startIndex + "---" + endIndex); new DownLoadThread(startIndex, endIndex, i).start(); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }class DownLoadThread extends Thread{ int startIndex; int endIndex; int threadId; public DownLoadThread(int startIndex, int endIndex, int threadId) { super(); this.startIndex = startIndex; this.endIndex = endIndex; this.threadId = threadId; } @Override public void run() { //再次發送http請求,下載原檔案 try { File progressFile = new File(threadId + ".txt"); //判斷進度臨時檔案是否存在 if(progressFile.exists()){ FileInputStream fis = new FileInputStream(progressFile); BufferedReader br = new BufferedReader(new InputStreamReader(fis)); //從進度臨時檔案中讀取出上一次下載的總進度,然後與原本的開始位置相加,得到新的開始位置 startIndex += Integer.parseInt(br.readLine()); fis.close(); } System.out.println("線程" + threadId + "的下載區間是:" + startIndex + "---" + endIndex); HttpURLConnection conn; URL url = new URL(MultiDownload.path); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); //設定本次http請求所請求的資料的區間 conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex); //請求部分資料,相應碼是206 if(conn.getResponseCode() == 206){ //流裡此時只有1/3原檔案的資料 InputStream is = conn.getInputStream(); byte[] b = new byte[1024]; int len = 0; int total = 0; //拿到臨時檔案的輸出資料流 File file = new File("QQPlayer.exe"); RandomAccessFile raf = new RandomAccessFile(file, "rwd"); //把檔案的寫入位置移動至startIndex raf.seek(startIndex); while((len = is.read(b)) != -1){ //每次讀取流裡資料之後,同步把資料寫入臨時檔案 raf.write(b, 0, len); total += len;// System.out.println("線程" + threadId + "下載了" + total); //產生一個專門用來記錄下載進度的臨時檔案 RandomAccessFile progressRaf = new RandomAccessFile(progressFile, "rwd"); //每次讀取流裡資料之後,同步把當前線程下載的總進度寫入進度臨時檔案中 progressRaf.write((total + "").getBytes()); progressRaf.close(); } System.out.println("線程" + threadId + "下載完畢-------------------小志參上!"); raf.close(); //把記錄進程的檔案刪除 必須3個進程全部都下載完成後才可以刪除 MultiDownload.finishedThread++; synchronized (MultiDownload.path) { //有安全執行緒問題,靜態變數為唯一的 if(MultiDownload.finishedThread == MultiDownload.ThreadCount){ for (int i = 0; i < MultiDownload.ThreadCount; i++) { File f = new File(i + ".txt"); f.delete(); } MultiDownload.finishedThread = 0; } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
java多線程下載檔案和斷點下載