DownloadFile.java
package test.utils;import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.IOException;import java.io.RandomAccessFile;import java.io.UnsupportedEncodingException;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLDecoder;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/** * java 多執行緒下載檔案 */public class DownloadFile { public static void main(String[] args) { DownloadFile df = new DownloadFile(); try { List<String> urlList = new ArrayList<String>(); df.readFileByLines("f:\\Download\\url.txt", urlList); int l = urlList.size(); for (int i = 0; i < l; i++) { df.download(urlList.get(i), "f:\\Download"); } } catch (Exception e) { e.printStackTrace(); } } /** * 下載檔案 * @param urlStr * @param dirStr */ public void download(String urlStr, String dirStr) { RandomAccessFile osf = null; File dir = new File(dirStr); dir.mkdirs(); try { String fileName = dirStr + "\\" + getFileName(urlStr); File ff = new File(fileName); if (ff.exists()) { ff.delete(); } System.out.println(fileName + ":::" + urlStr); URL url = new URL(urlStr); HttpURLConnection http = (HttpURLConnection) url.openConnection(); if (404 == http.getResponseCode()) { System.out.println(urlStr + "下載失敗,下載的檔案不存在"); return; } int httpLen = http.getContentLength(); int tn = 5;//設定5個執行緒下載一個檔案 int len = httpLen / tn;// 捨去餘數計算每個執行緒應下載平均長度,最後一個執行緒再加上餘數,則是整個檔案的長度 File f = new File(fileName); if (f.exists()) { f.delete(); osf = new RandomAccessFile(f, "rw"); osf.seek(httpLen - 1); osf.write(0); } else { osf = new RandomAccessFile(f, "rw"); osf.seek(httpLen - 1); osf.write(0); } int bn = 0;// 每個執行緒寫入檔案的位元組數 for (int j = 0; j < tn; j++) { if (j == tn - 1) {//最後一個執行緒加上餘數長度位元組 bn = len + (httpLen % tn); } else { bn = len; } Thread t = new DownloadThread(j, urlStr, fileName, len * j, bn); t.start(); } } catch (Exception e) { e.printStackTrace(); System.out.println("error:" + urlStr); } finally { if (null != osf) { try { osf.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 獲取檔名 * @param url * @return String * @throws UnsupportedEncodingException */ public String getFileName(String url) throws UnsupportedEncodingException { String a = URLDecoder.decode(url, "utf-8"); int s = a.lastIndexOf("/") + 1; int e = a.lastIndexOf("?"); if (e > -1) { return a.substring(s, e); } String fileName = a.substring(s); System.out.println(fileName); return fileName; } /** * 讀下載地址檔案 * @param fileName * @param urlList */ private void readFileByLines(String fileName, List<String> urlList) { File file = new File(fileName); BufferedReader reader = null; StringBuilder sb = new StringBuilder(); Map<String, String> m = new HashMap<String, String>(); try { System.out.println("以行為單位讀取檔案內容,一次讀一整行:"); reader = new BufferedReader(new FileReader(file)); // reader = new BufferedReader(new InputStreamReader(new // FileInputStream(fileName),"ISO-8859-1")); String tempString = null; // 一次讀入一行,直到讀入null為檔案結束 while ((tempString = reader.readLine()) != null) { sb.append(tempString); if (!m.containsKey(tempString)) { urlList.add(tempString); m.put(tempString, ""); } } System.out.println(urlList.size()); reader.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e1) { e1.printStackTrace(); } } } }}
DownloadThread.java
package test.utils;import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.io.RandomAccessFile;import java.math.BigDecimal;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;public class DownloadThread extends Thread { String httpUrl; int start; int end; String fileName; RandomAccessFile osf; boolean f = false; public DownloadThread(int i, String httpUrl, String fileName, int start, int end) { this.setName("t" + i); // 子執行緒名稱 this.httpUrl = httpUrl; // 下載地址 this.fileName = fileName; this.start = start; // 子執行緒讀取/寫入起始位元組 this.end = end;// 子執行緒寫入結束位元組長度 } public void run() { try { osf = new RandomAccessFile(fileName, "rw"); URL url = new URL(httpUrl); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setRequestProperty("User-Agent", "download");// 自定義ua,可以模擬任何瀏覽器 httpURLConnection.setRequestProperty("RANGE", "bytes=" + start + "-");// 設定斷點位置,向伺服器請求從檔案哪個位元組開始讀取 osf.seek(start);// 設定檔案從哪個位元組開始寫入 InputStream input = httpURLConnection.getInputStream(); int cacheSize = 2048; byte b[] = new byte[cacheSize];// 設定緩衝池,每次只讀2048位元組 int l = 0;// 計算子執行緒讀取和寫入檔案長度,當長度大於每個子執行緒平均下載長度則終止執行緒 int c = 0;// System.out.println(this.getName()+" 開始下載。。。");// Date startDate=new Date();//子執行緒開始下載時間 double fff = -1; while ((c = input.read(b, 0, cacheSize)) != -1 && (l <= end)) {// 執行緒下載位元組長度控制誤差小於緩衝池大小 osf.write(b, 0, c); b = new byte[cacheSize];// 重新初始化,避免讀入舊資料 l += c; double f = ((double) l / (double) end); BigDecimal bg = new BigDecimal(f); double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); double fa = f1 * 100; if (fa > fff) { System.out.println(this.getName() + "---" + fileName + ": " + fa + "%"); fff = fa; } if (fa >= 100) { break; } } System.out.println(this.getName() + "---" + fileName + " finish");// Date endDate=new Date();//子執行緒結束下載時間// System.out.println(this.getName()+" 執行緒耗時: "+(endDate.getTime()-startDate.getTime())/1000+" 秒,實際共下載:"+l+ "位元組");// 子執行緒下載耗時(秒) } catch (FileNotFoundException e1) { System.out.println(fileName); f = true; } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (null != osf) { try { osf.close(); } catch (IOException e) { e.printStackTrace(); } } if (f) { File f = new File(fileName); f.delete(); } } }}
最新評論
熱門排行
- GC類壓力管道安裝資質辦理,氨製冷(冷庫)管道定期檢驗程序
- 幾種PCBA表面處理的類型
- 歌禮制藥-B(01672)宣佈口服PD-L1小分子抑制劑前藥ASC61 用於治療晚期實體瘤的美國I期臨床試驗完成首例患者給藥
- 深耕CRO服務領域 宣泰醫藥(688247.SH)擬首次公開發行4534萬股
- 壓力容器許可證資質辦理,鉻鉬鋼製壓力容器結構設計規定
- 家裡有點地,這種果樹種上兩棵,栽到花盆裡,夏天就能結果子
- 家裡養株“大將軍”蘭花,花色喜慶,花大如盆,打理很簡單
- 庫存飆升!韓國半導體庫存激增80%
- 多點DMALL合夥人劉桂海:多點DMALL實踐實體零售數字化轉型
- 豬各階段拉稀的原因和解決方案,這篇文章告訴你答案,值得收藏