前言:java
程序下載文件時,有時會由於各類各樣的緣由下載中斷,對於小文件來講影響不大,能夠快速從新下載,可是下載大文件時,就會耗費很長時間,因此斷點續傳功能對於大文件頗有必要。git
文件下載的斷點續傳:spring
一、先下載臨時文件,用於記錄已下載大小:dom
二、http請求時設置Range參數ide
三、下載這次請求的數據;url
直接上代碼:spa
1 package com.test.service; 2 3 import java.io.File; 4 import java.io.InputStream; 5 import java.io.RandomAccessFile; 6 import java.net.HttpURLConnection; 7 import java.net.URL; 8 import java.text.NumberFormat; 9 10 import org.slf4j.Logger; 11 import org.slf4j.LoggerFactory; 12 import org.springframework.beans.factory.annotation.Value; 13 import org.springframework.stereotype.Component; 14 15 /** 16 * <p> 17 * 文件下載,能夠支持斷點續傳 18 * 暫未使用 19 * </p> 20 * @author 21 * @version 1.0 22 * */ 23 @Component 24 public class DownloadOnly { 25 26 private static final Logger logger = LoggerFactory.getLogger(DownloadOnly.class); 27 28 @Value("${onair.download.ddxc:true}") 29 boolean ddxc = true; 30 31 int startIndex = 0; 32 33 long downloadSize = 0; 34 35 boolean downloadFinish = false; 36 37 int totleSize = 0; 38 39 public boolean download(String url,String file_path,int downloadTimeout){ 40 41 //起一個線程 檢測下載進度 42 new Thread(new Runnable() { 43 44 @Override 45 public void run() { 46 try { 47 NumberFormat nt = NumberFormat.getPercentInstance(); 48 //設置百分數精確度3即保留三位小數 49 nt.setMinimumFractionDigits(1); 50 while(!downloadFinish){ 51 Thread.sleep(30000); 52 logger.debug("已下載大小{},進度{}",getDownloadSize(),nt.format(getDownloadSize()* 1.0 /totleSize)); 53 } 54 } catch (InterruptedException e) { 55 e.printStackTrace(); 56 } 57 58 } 59 }).start(); 60 61 logger.info("下載文件:源路徑{},目標路徑:{}",url,file_path); 62 RandomAccessFile raf = null; 63 InputStream in = null; 64 65 try { 66 URL file_url = new URL(url); 67 HttpURLConnection conn = (HttpURLConnection)file_url.openConnection(); 68 conn.setConnectTimeout(downloadTimeout); 69 conn.setRequestMethod("GET"); 70 File tmpFile = new File(file_path+"_tmp"); 71 if(ddxc){ 72 if(tmpFile.exists() && tmpFile.isFile()){ 73 downloadSize = tmpFile.length(); 74 startIndex = (int)downloadSize; 75 } 76 conn.setRequestProperty("Range", "bytes=" + startIndex + "-"); 77 }else{ 78 if(tmpFile.exists() && tmpFile.isFile()) 79 tmpFile.delete(); 80 } 81 int status = conn.getResponseCode(); 82 totleSize = (int)downloadSize + conn.getContentLength(); 83 logger.info("文件總大小{},下載請求得到的返回狀態碼:{},須要下載的大小{}",totleSize,status,totleSize-downloadSize); 84 if(status== 200 || status == 206 ){ 85 raf = new RandomAccessFile(tmpFile, "rwd"); 86 raf.seek(startIndex); 87 in = conn.getInputStream(); 88 byte[] buffer = new byte[1024]; 89 int size = 0; 90 while((size=in.read(buffer)) !=-1 ){ 91 raf.write(buffer, 0, size); 92 downloadSize += size; 93 } 94 raf.close(); 95 in.close(); 96 File dest = new File(file_path); 97 return tmpFile.renameTo(dest); 98 } 99 } catch (Throwable e) { 100 logger.error("文件下載失敗:{}",e.getMessage(),e); 101 }finally { 102 downloadFinish = true; //下載完成或中斷 103 } 104 return false; 105 } 106 107 public long getDownloadSize() { 108 return downloadSize; 109 } 110 111 public static void main(String[] args) { 112 DownloadOnly downloadOnly = new DownloadOnly(); 113 } 114 115 }