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 }
时间: 2024-10-03 20:33:49

Java单线程文件下载,支持断点续传功能的相关文章

【Flume】flume文件监控的source组件开发,支持断点续传功能

基于flume-ng中原有exec的source类型,通过tail依赖于操作系统去监听文件内容变化,其次,不支持断点续传的功能,特此,自行开发了一个组件,大家可以看看,一起探讨: https://github.com/cwtree/flume-filemonitor-source 望各位不吝指教!

Java多线程下载器FileDownloader(支持断点续传、代理等功能)

前言 在我的任务清单中,很早就有了一个文件下载器,但一直忙着没空去写.最近刚好放假,便抽了些时间完成了下文中的这个下载器. 介绍 同样的,还是先上效果图吧. Jar包地址位于 FileDownloader 目前实现的主要功能有: 多线程下载 断点续传 自定义头部等 即将完成的包括: 添加代理功能 ... 感觉做了回标题党,代理功能由于时间关系,将在下次更新加入. 关于设置代理,我这篇文章 Java实现Ip代理池 中有具体的设置方法. 另外除了这个代理功能,我也实在不知道下载器能加些啥功能了..

edtftpj让Java上传FTP文件支持断点续传

在用Java实现FTP上传文件功能时,特别是上传大文件的时候,可以需要这样的功能:程序在上传的过程中意外终止了,文件传了一大半,想从断掉了地方继续传:或者想做类似迅雷下载类似的功能,文件太大,今天传一半,睡一觉去先,明天继续传. Java上传FTP文件,用的比较多的工具是apache的commons-net.如果想用commons-net实现FTP上传的断点续传还是有点麻烦. 除了commons-net之外,还有很多非常优秀的FTP工具,这里使用edtftpj这个工具来实现断点续传. 下载:ht

Java实现的断点续传功能

代码中已经加入了注释,需要的朋友可以直接参考代码中的注释.下面直接上功能实现的主要代码: import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.Malfor

php 支持断点续传的文件下载类

php 支持断点续传的文件下载类 分类: php class2013-06-30 17:27 17748人阅读 评论(6) 收藏 举报 php断点续传下载http测试 php 支持断点续传,主要依靠HTTP协议中 header HTTP_RANGE实现. HTTP断点续传原理Http头 Range.Content-Range()HTTP头中一般断点下载时才用到Range和Content-Range实体头,Range用户请求头中,指定第一个字节的位置和最后一个字节的位置,如(Range:200-3

【Servlet】java web 文件下载功能实现

需求:实现一个具有文件下载功能的网页,主要下载压缩包和图片 两种实现方法: 一:通过超链接实现下载 在HTML网页中,通过超链接链接到要下载的文件的地址 [html] view plain copy <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body&

php实现的支持断点续传的文件下载类

通常来说,php支持断点续传,主要依靠HTTP协议中 header HTTP_RANGE实现. HTTP断点续传原理: Http头 Range.Content-Range()HTTP头中一般断点下载时才用到Range和Content-Range实体头,Range用户请求头中,指定第一个字节的位置和最后一个字节的位置,如(Range:200-300)Content-Range用于响应头 请求下载整个文件: GET /test.rar HTTP/1.1 Connection: close Host:

一个简单Android下载管理器的实现(支持断点续传)

近期工作不是很忙,时间比较多,所以在空闲时间准备自己编写一个简单的Android下载管理器.该管理器实现如下功能: 1.能够支持正常的下载,暂停,继续,安装操作. 2.支持断点续传,实现暂停继续功能,在推出应用后,再次进入应用依然能正常将文件下载完成. 3.实现实时状态回调,下载进度,速度,一目了然. 以上是UML设计图,这个简单下载器的实现,有几个技术难点,攻克它们问题就迎刃而解. 1.如何实现断点续传:这个问题其实不难,网上也有很多相关资料,基本原理都相同,就是记录下载任务上一次中断的位置,

在ASP.NET中支持断点续传下载大文件(ZT)

IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头. 一. 两个必要响应头Accept-Ranges.ETag         客户端每次提交下载请求时,服务端都要添加这两个响应头,以保证客户端和服务端将此下载识别为可以断点续传的下载: Accept-Ranges:告知下载客户端这是一个可以恢复续传的下载,存放本次下载的开始字节位置.文件的字节大小: ETag:保存文件的唯一标识(我在用的文件名+文件最后修改时间,以便续传请求时对文件进行