zoukankan      html  css  js  c++  java
  • Java单线程文件下载,支持断点续传功能

    前言:

           程序下载文件时,有时会因为各种各样的原因下载中断,对于小文件来说影响不大,可以快速重新下载,但是下载大文件时,就会耗费很长时间,所以断点续传功能对于大文件很有必要。

    文件下载的断点续传:

      1、先下载临时文件,用于记录已下载大小:

            2、http请求时设置Range参数

            3、下载此次请求的数据;

    直接上代码:

      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 }
  • 相关阅读:
    linux常用命令三
    linux常用命令二
    redis持久化
    Linux环境redis集群搭建
    Maven常用命令
    Maven生成项目站点
    maven中import scope依赖方式解决单继承问题的理解
    maven使用assembly打包tar.gz文件
    Apache CXFjar包目录(转)
    WebService学习笔记一
  • 原文地址:https://www.cnblogs.com/liangblog/p/7262678.html
Copyright © 2011-2022 走看看