<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
java的多執行緒下載能夠明顯提升下載的速度,平時我們用的迅雷軟體之所以能夠下載那麼快,就是使用了多執行緒;當用戶在下載的過程中,有斷電或斷網的可能,當用戶再次點選下載時,應該讓使用者接著原來的進度進行下載,這可以節約使用者的流量,所以要用到斷點續傳的功能。下面是通過Java程式碼實現多執行緒下載和斷點續傳的詳細程式碼。
1、建立一個類,用於檔案的下載
package com.edu.thread; 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; public class MultiDownload2 { static String path = "http://localhost:8080/wlan.zip"; //開啟執行緒的數量 static int threadCount = 6; //下載結束的執行緒數 static int threadFinished = 0; public static void main(String[] args) { 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("d://檔案測試", getFileName(path)); //建立隨機儲存檔案大小,為了建立一個和原始檔大小相同的儲存區間 RandomAccessFile raf = new RandomAccessFile(file, "rwd"); //設定臨時檔案的大小,和伺服器檔案一模一樣 raf.setLength(length); //計算每個執行緒下載的位元組數 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) { //length從0開始讀,所以length-1表示最後一個位元組 endIndex = length-1; } //列印三個執行緒的開始與結束位置 System.out.println("執行緒"+i+"的開始和結束位置:"+startIndex+"----"+endIndex); //開啟執行緒,傳入執行緒ID,下載的開始位置和下載的結束位置 new DownloadThread(i, startIndex, endIndex).start();; } } } catch (Exception e) { e.printStackTrace(); } } /* * 獲取檔名 */ public static String getFileName(String path){ int index=path.lastIndexOf("/"); return path.substring(index + 1); } }
2、建立另一個類,用於開啟子執行緒
package com.edu.thread; 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 DownloadThread extends Thread{ int thredId; int startIndex; int endIndex; public DownloadThread(int thredId, int startIndex, int endIndex) { super(); this.thredId = thredId; this.startIndex = startIndex; this.endIndex = endIndex; } public void run() { try { //下載進度檔案儲存的路徑和檔名 File progressFile = new File("d://檔案測試",(thredId + ".txt")); //判斷儲存下載進度的臨時檔案是否存在,以便確定下載的開始位置 if (progressFile.exists()) { FileInputStream fis = new FileInputStream(progressFile); BufferedReader bReader = new BufferedReader(new InputStreamReader(fis)); //拿到臨時檔案中儲存的資料,並把此資料設定為新的開始位置 int text = Integer.parseInt(bReader.readLine()); startIndex = text; fis.close(); } System.out.println("執行緒"+thredId+"的最終開始下載位置是:"+startIndex); URL url = new URL(MultiDownload2.path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); //設定請求資料的範圍 conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); //建立連線,狀態碼206表示請求部分資料成功,此時開始下載任務 if (conn.getResponseCode()==206) { InputStream is = conn.getInputStream(); //指定檔名和檔案路徑 File file = new File(MultiDownload2.getFileName(MultiDownload2.path) ); int len = 0; byte [] b = new byte[1024]; //三個執行緒各自建立自己的隨機儲存檔案 RandomAccessFile raf = new RandomAccessFile(file, "rwd"); //設定資料從哪個位置開始寫入資料到臨時檔案 raf.seek(startIndex); //設定當前執行緒下載的總位元組數 int total = 0; long start = System.currentTimeMillis(); //當下載意外停止時,記錄當前下載進度 int currentPosition = startIndex; while ((len=is.read(b))!=-1) { raf.write(b,0,len); //列印當前執行緒下載的總位元組數 total += len; /** * 實現斷點續傳的功能 */ //RandomAccessFile主要用來存放下載的臨時檔案,可以用FileOutputStream代替 RandomAccessFile rafProgress = new RandomAccessFile(progressFile, "rwd"); //再次下載時的開始位置 currentPosition = startIndex + total; //把下載進度寫進rafProgress臨時檔案,下一次下載時,就以這個值作為新的startIndex rafProgress.write((currentPosition + "").getBytes()); //關流 rafProgress.close(); System.out.println("執行緒"+thredId+"已經下載了"+total); } raf.close(); long end = System.currentTimeMillis(); //列印執行緒下載檔案用時 System.out.println("執行緒"+thredId+"下載檔案用時"+(end-start)+"ms"); //列印執行緒的結束 System.out.println("執行緒:"+thredId+" 下載結束了 !!!"); //下載結束後,刪除所有的臨時檔案 MultiDownload2.threadFinished ++; //使用同步語句塊,保證執行緒的安全性 synchronized (MultiDownload2.path) { //如果這個條件成立,說明所有的執行緒下載結束 if (MultiDownload2.threadFinished == MultiDownload2.threadCount) { for (int i = 0; i < MultiDownload2.threadCount; i++) { //刪除三個執行緒產生的臨時檔案 File temp = new File("d://檔案測試", i + ".txt"); temp.delete(); } //保證三個執行緒的臨時檔案同時被刪除 MultiDownload2.threadFinished = 0; } } } } catch (Exception e) { e.printStackTrace(); } } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45