需求:

支持文件批量下载。现在有很多小图片需要批量下载,不希望在服务器打包下载。

支持大文件断点下载。比如下载10G的文件。

PC端全平台支持。Windows,macOS,Linux

全浏览器支持。ie6,ie7,ie8,ie9,ie10,ie11,edge,firefox,chrome,safari

支持文件夹结构下载。不希望在服务器打包,而是直接下载文件夹,下载后在本地文件夹结构和服务器保持一致。

支持从URL中下载文件。

支持JSON数据结构。

说明

用java实现文件的断点续传,使用了HTTP的首部字段实现,在网上看到例子,手动实现一遍,理解其原理,在这记录下

正文

要实现断点续传,要在请求中设置请求开始的位置和结束位置,在HTTP请求中设置RANGE首部字段,之后服务器如果能正常返回,返回206状态码

用java实现的关键点:

1.设置请求的首部字段,使用java的net包

2.在读取资源文件后,要保存文件,从断点处保存,使用RandAccessFile类

3.使用多线程并发的方式进行,如何正确设置起始位置

主要思路就是:

1. 设置文件信息,包括文件所在的URL,文件名,文件保存的路径及文件需要分段下载的次数

2. 下载时,先连接服务器,得到文件的大小,通过服务器响应的首部字段Content-Length获得,得到文件大小后,根据分段下载的次数设置每次开始的位置,结束位置。并创造一个信息临时文件,用来保存每次分段下载的起始位置,用于非第一次下载时,可以直接本地读取起始信息

3. 分段下载根据开始位置,保存在下载文件的合适位置,使用RandAccessFile类的seek()方法定位

文件分块下载代码

<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%@page contentType="text/html;charset=UTF-8"%>

<%@page import="down2.*" %>

<%@page import="java.net.URLDecoder" %>

<%@page import="java.net.URLEncoder" %>

<%@page import="org.apache.commons.lang.*" %>

<%@page import="com.google.gson.FieldNamingPolicy" %>

<%@page import="com.google.gson.Gson" %>

<%@page import="com.google.gson.GsonBuilder" %>

<%@page import="com.google.gson.annotations.SerializedName" %>

<%@page import="java.io.*" %>

<% out.clear();

/*

下载数据库中的文件。

更新记录:

2015-05-13 创建

2017-12-09 完善Range协议

*/

String fileName = "网易云音乐.exe";//客户端保存的文件名

String filePath = "d:\\文件校验工具.exe";//路径

fileName = URLEncoder.encode(fileName,"UTF-8");

fileName = fileName.replaceAll("\\+","%20");

response.setContentType("application/octet-stream;charset:utf-8");

response.addHeader("Content-Disposition","attachment;filename=" + fileName);

response.addHeader("Pragma", "No-cache");

response.addHeader("Cache-Control", "No-cache");

response.addHeader("Expires", "0");

//定位文件块索引

File f = new File(filePath);

long fileLen = f.length();

long blockSize = fileLen;//块大小

long blockBegin = 0;

long blockEnd = 0;

RandomAccessFile raf = new RandomAccessFile(filePath,"r");

FileInputStream in = new FileInputStream( raf.getFD() );

String range = request.getHeader("Range");

if(range != null)

{

//清除bytes=

int pos = range.indexOf("=");

if(pos != -1) range = range.substring(pos+1);

/*

1-

-1

0-1

*/

String[] rs = range.split("-");//bytes=10254

//-1

if( StringUtils.isEmpty(rs[0]) )

{

blockSize = Long.parseLong(rs[1]);

in.skip(fileLen - blockSize);

blockEnd = fileLen - 1;

blockBegin = fileLen - blockSize;

}//1-

elseif( StringUtils.isEmpty(rs[1]))

{

blockBegin = Long.parseLong(rs[0]);

in.skip(blockBegin);

blockSize = fileLen - blockBegin;

blockEnd = (blockBegin + blockSize) - 1;

}//1-1

else

{

blockBegin = Long.parseLong(rs[0]);

blockEnd = Long.parseLong(rs[1]);

blockSize = (blockEnd - blockBegin) + 1;

in.skip(blockBegin);

}

}

response.addHeader("Content-Length",Long.toString(blockSize));

response.addHeader("Content-Range",String.format("bytes %d-%d/%d",blockBegin,blockEnd,fileLen) );

byte[] b = newbyte[1048576];//一次读1MB数据,如果服务器内存足够,可适当调大尺寸。

int i = 0;

OutputStream outp = response.getOutputStream();

while((i = in.read(b)) > 0)

{

outp.write(b, 0, i);

}

outp.flush();

in.close();

outp.close();

in  = null;

outp = null;

%>

2、文件的保存

文件保存由前端实现。由用户下载前选择文件的下载路径。

3、批量下载

批量下载通过urls参数即可实现。

$("#btn-down-files").click(function (){

if(downer.Config["Folder"]==""){ downer.open_folder();return;}

var urls =[

{ fileUrl:"http://res2.ncmem.com/res/images/ie11.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/up6.1/down.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/firefox.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/edge.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/up6.1/cloud.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/home/w.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/img.png"}

];

downer.app.addUrls(urls);

});

4、自定义下载文件夹名称

基本信息包含了文件所在站点信息,文件本地保存路径,文件名,文件分段下载次数

$("#btn-down-json").click(function (){

if(downer.Config["Folder"]==""){ downer.open_folder();return;}

var fd ={

nameLoc:"图片列表"

, files:[

{ fileUrl:"http://res2.ncmem.com/res/images/ie11.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/up6.1/down.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/firefox.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/edge.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/up6.1/cloud.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/home/w.png"}

,{ fileUrl:"http://res2.ncmem.com/res/images/img.png"}

]

};

downer.app.addJson(fd);

});

5、下载多级目录

//下载多级目录

$("#btn-down-fd").click(function (){

if(downer.Config["Folder"]==""){ downer.open_folder();return;}

var fd ={

nameLoc:"测试文件夹"

, files:[

{ fileUrl:"http://www.ncmem.com/images/ico-ftp.jpg"}

,{ fileUrl:"http://www.ncmem.com/images/ico-up.jpg"}

]

, folders:[

{

nameLoc:"图片1"

, files:[

{ fileUrl:"http://www.ncmem.com/images/ico-ftp.jpg"}

,{ fileUrl:"http://www.ncmem.com/images/ico-up.jpg"}

,{ fileUrl:"http://www.ncmem.com/images/ico-capture.jpg"}

,{ fileUrl:"http://www.ncmem.com/images/ico-imageuploader.gif"}

,{ fileUrl:"http://www.ncmem.com/images/ico-wordpaster.gif"}

]

, folders:[

{

nameLoc:"软件"

, files:[

{ fileUrl:"http://res2.ncmem.com/res/images/edit-file.png"}

]

}

]

}

]

};

downer.app.addJson(fd);

});

网上例子:http://blog.ncmem.com/wordpress/2019/08/28/java批量下载/

用java实现文件的断点续传并发下载的更多相关文章

  1. java实现文件的断点续传的下载

    java的断点续传是基于之前java文件下载基础上的功能拓展 首先设置一个以线程ID为名的下载进度文件, 每一次下载的进度会保存在这个文件中,下一次下载的时候,会根据进度文件里面的内容来判断下载的进度 ...

  2. java实现文件的断点续传

    java实现文件的断点续传: 依赖: <!--文件上传--> <dependency> <groupId>commons-fileupload</groupI ...

  3. java的文件上传和下载 抄袭别人的.在底部有说明.

    =======后续 这里采用的是输出流的方式,我电脑装的是windows系统,测试没有问题,但是当把项目放到Linux系统上跑时,就会出现保存位置错误的情况, 指定的路径就会被当做文件名的一部分保存了 ...

  4. Java实现文件的上传下载

    文件上传,下载的方法: 上传代码 /** * 文件上传.保存 * * @param mapping * @param form * @param request * @param response * ...

  5. Java 实现文件上传、下载、打包、文件copy、文件夹copy。

    文件and文件夹copy package org.test; import java.io.*; public class FileCopy { /** * 复制单个文件 * * @param old ...

  6. http文件的断点续传和下载

    http://www.tuicool.com/articles/ZbyymqJ Content-Disposition:inline; filename= "c501b_01_h264_sd ...

  7. Java Struts文件上传和下载详解

    Struts2文件上传 Struts 2框架提供了内置支持处理文件上传使用基于HTML表单的文件上传.上传一个文件时,它通常会被存储在一个临时目录中,他们应该由Action类进行处理或移动到一个永久的 ...

  8. JAVA SFTP文件上传、下载及批量下载

    JavaJsch  1.jsch官方API查看地址(附件为需要的jar) http://www.jcraft.com/jsch/ 2.jsch简介 JSch(Java Secure Channel)是 ...

  9. java+超大文件上传与下载

    ​这里先说下spring mvc 遇到的坑,就是如果文件上传时,后端这样写public String file1(HttpServletRequest request),根据request拿到的东西是 ...

随机推荐

  1. QTP技术支持之QTP对象无法识别(转自582357212的个人空间,链接:http://www.51testing.com/html/64/305564-847787.html)

    QTP自动化测试从业者,或者很多练习使用QTP开发自动化测试代码的人员遇到最多的问题恐怕就是对象无法识别了,对象无法识别原因有很多种,根据经常对QTP自动化测试脚本开发人员的技术Support,我总结 ...

  2. c# Thread5——线程同步之基本原子操作。Mutex互斥量的使用

    之前的博文也说到了如果多线程对于访问的公共资源操作都是原子操作,那么可以避免竞争条件.关于多线程的竞争可以百度. 1.执行最基本的原子操作 c#提供了一系列供我们使用的原子操作的方法和类型,比如我们的 ...

  3. 自动化测试--利用opencv进行图像识别与定位

    SIFT检测方法 SIFT算法就是把图像的特征检测出来,通过这些特征可以在众多的图片中找到相应的图片 import cv2 #读取图片,以1.png为例 img=cv2.imread('1.png') ...

  4. oracle--表分区、分区索引

    --|/ range分区 create table sale( product_id varchar2(5), sale_count number(10,2) ) partition by range ...

  5. PTA第四周作业

    一.本周完成的作业 7-2 选择法排序 (20 分) 本题要求将给定的n个整数从大到小排序后输出. 输入格式: 输入第一行给出一个不超过10的正整数n.第二行给出n个整数,其间以空格分隔. 输出格式: ...

  6. levelDB SSTable-静态布局结构

    SSTable是Bigtable中至关重要的一块,对于LevelDB来说也是如此,对LevelDB的SSTable实现细节的了解也有助于了解Bigtable中一些实现细节.     本节内容主要讲述S ...

  7. Mybatis-学习笔记(2)Mybatis配置文件

      3>typeAliases:类型别名.2种指定方式. 1>给某个类起个别名 <typeAliases> <typeAlias type="com.lfy.b ...

  8. java 泛型的内部原理:类型擦除以及类型擦除带来的问题

    一.Java泛型的实现方法:类型擦除前面已经说了,Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首要前提是理解类型擦出(ty ...

  9. 在WebStorm中使用editorConfig插件

    在webStorm中默认是支持editorConfig插件的,那么我们需要在webStorm中自定义editorConfig的配置怎么来做? 第一步:打开webStrome > File > ...

  10. AppDomain (转)

    AppDomain是CLR的运行单元,它可以加载Assembly.创建对象以及执行程序.AppDomain是CLR实现代码隔离的基本机制. 每一个AppDomain可以单独运行.停止:每个AppDom ...