关于java:突破某度云盘下载限速提速30倍想学我教你啊

4次阅读

共计 2505 个字符,预计需要花费 7 分钟才能阅读完成。

前言

在上一篇文章《面试官不讲武德》对 Java 高级程序猿死命摩擦 Http 协定 中,咱们有提到大文件下载和断点续传,本篇咱们就来开发一个多线程文件下载器,最初咱们用这个多线程下载器来冲破百度云盘下载的限速。

兄弟们看到这个题目可能会感觉是个题目党,为了解决疑虑,咱们先来看下最终的测试后果:

测试百度云下载的文件 46M,本人本地最大下载速度 2M

1. 单线程下载,总耗时: 603s

2. 多线程下载,50 个线程,总耗时:13s

测试后果,提速 46 倍,我还是太虚心了,只说提速 30 倍,此处咱们感觉应该有掌声(我听不到,还是点赞切实)

源码地址:https://gitee.com/silently9527/fast-download

喜爱请记得 star 哦


HTTP 协定 Range 申请头

Range 次要是针对只须要获取局部资源的范畴申请,通过指定 Range 即可告知服务器资源的指定范畴。格局: Range: bytes=start-end

比方:
获取字节范畴 5001-10000

Range: bytes=5001-10000

也能够指定开始地位不指定完结地位,示意获取开始地位之后的全副数据

Range: bytes=5001-

服务器接管到带有 Range 的申请,会在解决申请之后返回状态码为 206 Partial Content 的响应。

基于 Range 的个性,咱们就能够实现文件的多线程下载,文件的断点续传

筹备工作

本文咱们应用的 SpringMVC 中的 RestTemplate;因为百度云的链接是 Https,所以咱们须要设置RestTemplate 绕过证书验证

  1. pom.xml

  1. 编写 RestTemplate 的结构器,以及绕过 https 的证书验证

  1. 在下载的过程中,咱们须要晓得以后下载的速度是多少,所以须要定义一个显示下载速度的接口

因为计算下载速度,咱们须要晓得每秒传输的字节数是多少,为了监控传输数据的过程,咱们须要理解 SpringMVC 中的接口ResponseExtractor

该接口只有一个办法,当客户端和服务器端连贯建设之后,会调用这个办法,咱们能够在这个办法中监控下载的速度。

  1. DisplayDownloadSpeed接口的形象实现 AbstractDisplayDownloadSpeedResponseExtractor

  1. 整个我的项目次要波及到的类图

简略的文件下载器

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

这里咱们须要留神的点是: 这种形式会将文件的字节数组全副放入内存中, 及其耗费资源;咱们来看看如何实现。

  1. 创立 ByteArrayResponseExtractor 类继承AbstractDisplayDownloadSpeedResponseExtractor

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

  1. 测试下载 819M 的 idea

执行一段时间之后,咱们能够看到内存曾经应用了 800M 左右,所以这种形式只能应用于小文件的下载,如果咱们下载几 G 的大文件,内存必定是不够用的。至于下载工夫,因为文件太大也没有等下载实现就完结了程序。

单线程大文件下载

下面的形式只能下载小的文件,那大文件的下载咱们该用什么形式呢?咱们能够把流输入到文件而不是内存中。接下来咱们来实现咱们大文件的下载。

  1. 创立 FileResponseExtractor 类继承AbstractDisplayDownloadSpeedResponseExtractor,把流输入到文件中

  1. 文件下载器,先把流输入到长期下载文件(xxxxx.download),下载实现后在重命名文件

  1. 测试下载 819M 的 idea

执行一段时间之后,咱们再看看下内存的应用状况,发现这种形式内存耗费较少,成果比拟现实,下载工夫:199s

多线程文件下载

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

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

  1. 首先咱们通过 Http 协定的 Head 办法获取到文件的总大小
  2. 而后依据设置的线程数均分文件的大小,计算每个线程的下载的字节数据开始地位和完结地位
  3. 开启线程,设置 HTTP 申请头 Range 信息,开始下载数据到临时文件
  4. 下载实现后把每个线程下载实现的临时文件合并成一个文件

实现代码如下:

  1. 开启 30 个线程测试下载 819M 的 idea

从执行的后果上来看,因为开启了 30 个线程同时在下载,内存的占用要比单线程耗费的多,然而也在承受范畴内,下载工夫:81s,速度晋升 2.5 倍,这是因为 idea 的下载服务器没有限速,本次多线程速度的晋升仅仅是在充沛的压迫本地的带宽,所以提醒的幅度不大。

单线程下载和对线程下载比照测试

因为百度云盘对单个线程的下载速度做了限度,大略是在 100kb,所以咱们应用百度云盘的下载链接,来测试多线程和单线程的下载速度。

  1. 测试 百度云盘中 46M 的文件的下载速度,本人本地最大下载速度 2M
  2. 获取文件的下载地址

留神:从浏览器中获取的链接须要先应用 URLDecode 解码,否则下载会失败,并且百度云盘文件的下载链接是有时效性的,过期后就不能在下载,须要从新生成下载链接

测试单线程下载文件

执行的后果能够看出,百度云对单线程的下载限速真的是丧心病狂,46M 的文件下载须要耗时:600s

测试多线程下载文件

为了充沛的压迫网速,找出最合适的线程数,所以测试了不同线程数的下载速度

线程数 下载总耗时
10 60s
20 30s
30 21s
40 15s
50 13s

从测试的后果上来看,对于本人的运行环境把线程数设置在 30 个左右比拟适合


文件断点续传如何实现,欢送在大家评论区说出本人的思路。

写到最初(点关注,不迷路)

文中或者会存在或多或少的有余、谬误之处,有倡议或者意见也十分欢送大家在评论交换。

最初,创作不易,请不要白嫖 ,心愿敌人们能够 点赞评论关注 三连,因为这些就是我分享的全副能源起源????

原创不易 转载请注明出处:

本文纯正用于学习

正文完
 0