前言:
今天早上刷着B站,看到一个视频说有一个需求,如何实现下载限流,我就直接看了up是怎么做的:通过休眠线程 `Thread.sleep(1000);` 进行实现,我觉得感觉有点不太行,然后就有了这篇文章。
经典限流算法:一文秒解四大经典限流算法-CSDN博客
主要实现思路:控制每次读取文件时循环的时间,以限制下载速度。
具体实现:
-
首先,我们需要确定要下载的文件的URL和保存路径。在代码中,我们使用
fileUrl
变量存储文件的URL,使用savePath
变量存储文件的保存路径。 -
接下来,我们创建一个
HttpURLConnection
对象来与服务器建立连接。通过调用url.openConnection()
方法获取到URLConnection
对象,然后将其强制转换为HttpURLConnection
类型。 -
设置请求方法为GET,即通过HTTP GET请求从服务器获取文件内容。
-
连接到服务器,通过调用
connection.connect()
方法建立连接。 -
创建一个
BufferedInputStream
对象来读取服务器返回的数据流,并创建一个FileOutputStream
对象来将数据写入本地文件。 -
定义一个缓冲区数组
buffer
,用于存储每次读取的数据。 -
初始化一些变量,包括
bytesRead
表示每次读取的字节数,startTime
表示开始下载的时间,totalBytesRead
表示已读取的总字节数。 -
进入循环,不断从输入流中读取数据,直到读取完毕(即
bytesRead
等于-1)。 -
在循环中,将读取到的数据写入输出流,同时更新已读取的总字节数。
-
计算已经过去的时间,并根据限制速度计算出预期的时间。如果实际时间小于预期时间,则线程休眠一段时间,以控制下载速度。
-
最后,在循环结束后,断开与服务器的连接,释放资源。
package com.pxl.test;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownLoadLimiter {
private static final int BUFFER_SIZE = 4096;
private static final int THROTTLE_RATE = 1024; // 限制速度为1KB/s
public static void main(String[] args) {
//从哪里进行下载文件
String fileUrl = "https://foruda.gitee.com/images/1709900983960761725/13a99dda_13541524.png";
//将文件下载到何处
String savePath = "D:\\笔记\\ph1.png";
try {
downloadFileWithThrottle(fileUrl, savePath);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void downloadFileWithThrottle(String fileUrl, String savePath) throws IOException {
URL url = new URL(fileUrl);
//与服务器建立联系
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
try (BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());
FileOutputStream outputStream = new FileOutputStream(savePath)) {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
long startTime = System.currentTimeMillis();
int totalBytesRead = 0;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
long elapsedTime = System.currentTimeMillis() - startTime;
long expectedTime = totalBytesRead / THROTTLE_RATE;
if (elapsedTime < expectedTime) {
try {
Thread.sleep(expectedTime - elapsedTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} finally {
//断开连接
connection.disconnect();
}
}
}
这个只是一个简单的实现:
个人感觉还可以加上一些的限流算法来实现文件下载限流。