当前位置: 主页 > JAVA语言

java实现文件下载-绕过证书验证.xml编写RestTemplate的抽象实现

发布时间:2023-07-12 10:00   浏览次数:次   作者:佚名

Range主要是针对只需要获取部分资源的范围请求,通过指定Range即可告知服务器资源的指定范围。格式: Range: bytes=start-end

比如:获取字节范围 5001-10000

Range: bytes=5001-10000
1

也可以指定开始位置不指定结束位置,表示获取开始位置之后的全部数据

Range: bytes=5001-
1

服务器接收到带有Range的请求,会在处理请求之后返回状态码为206 Partial Content的响应。

基于Range的特性,我们就可以实现文件的多线程下载,文件的断点续传

准备工作

本文我们使用的SpringMVC中的RestTemplate;由于云盘的链接是Https,所以我们需要设置RestTemplate绕过证书验证

pom.xml

下载文件java写法_java实现文件下载_java实现文件下载功能

编写RestTemplate的构造器,以及绕过https的证书验证

java实现文件下载功能_下载文件java写法_java实现文件下载

在下载的过程中,我们需要知道当前下载的速度是多少,所以需要定义一个显示下载速度的接口

下载文件java写法_java实现文件下载功能_java实现文件下载

因为计算下载速度,我们需要知道每秒传输的字节数是多少,为了监控传输数据的过程,我们需要了解SpringMVC中的接口ResponseExtractor

java实现文件下载功能_下载文件java写法_java实现文件下载

该接口只有一个方法,当客户端和服务器端连接建立之后java实现文件下载,会调用这个方法,我们可以在这个方法中监控下载的速度。

DisplayDownloadSpeed接口的抽象实现 AbstractDisplayDownloadSpeedResponseExtractor

java实现文件下载_java实现文件下载功能_下载文件java写法

整个项目主要涉及到的类图

java实现文件下载_下载文件java写法_java实现文件下载功能

简单的文件下载器

这里使用的是restTemplate调用execute, 先文件获取到字节数组, 再将字节数组直接写到目标文件。

这里我们需要注意的点是: 这种方式会将文件的字节数组全部放入内存中, 及其消耗资源;我们来看看如何实现。

创建ByteArrayResponseExtractor类继承AbstractDisplayDownloadSpeedResponseExtractor

java实现文件下载_java实现文件下载功能_下载文件java写法

调用restTemplate.execute执行下载,保存字节数据到文件中

java实现文件下载_java实现文件下载功能_下载文件java写法

测试下载819M的idea

java实现文件下载_java实现文件下载功能_下载文件java写法

java实现文件下载功能_下载文件java写法_java实现文件下载

执行一段时间之后,我们可以看到内存已经使用了800M左右,所以这种方式只能使用于小文件的下载,如果我们下载几G的大文件,内存肯定是不够用的。至于下载时间,因为文件太大也没有等下载完成就结束了程序。

单线程大文件下载

上面的方式只能下载小的文件,那大文件的下载我们该用什么方式呢?我们可以把流输出到文件而不是内存中。接下来我们来实现我们大文件的下载。

创建FileResponseExtractor类继承AbstractDisplayDownloadSpeedResponseExtractor,把流输出到文件中

下载文件java写法_java实现文件下载功能_java实现文件下载

文件下载器,先把流输出到临时下载文件(xxxxx.download),下载完成后在重命名文件

java实现文件下载功能_java实现文件下载_下载文件java写法

测试下载819M的idea

下载文件java写法_java实现文件下载_java实现文件下载功能

执行一段时间之后java实现文件下载,我们再看看下内存的使用情况,发现这种方式内存消耗较少,效果比较理想,下载时间:199s

java实现文件下载_java实现文件下载功能_下载文件java写法

下载文件java写法_java实现文件下载_java实现文件下载功能

多线程文件下载

如果服务器不限速的话,通常能够把自己本地的带宽给跑满,那么使用单线程下载就够了,但是如果遇到服务器限速,下载速度远小于自己本地的带宽,那么可以考虑使用多线程下载。多线程我们使用CompletableFuture(可以参考文章 CompletableFuture让你的代码免受阻塞之苦)。

实现多线程文件下载的基本流程: