最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot實(shí)現(xiàn)文件下載的限速功能

 更新時(shí)間:2024年07月03日 11:13:40   作者:shy好好學(xué)習(xí)  
在SpringBoot項(xiàng)目中,實(shí)現(xiàn)文件下載的限速功能可以有效控制服務(wù)器帶寬的占用,并防止單個(gè)用戶消耗過多的資源,本文將通過具體的代碼示例和詳細(xì)的流程解釋,介紹如何在SpringBoot項(xiàng)目中實(shí)現(xiàn)文件下載的限速功能,需要的朋友可以參考下

前言

在文件下載過程中,如果不加以控制,可能會(huì)導(dǎo)致服務(wù)器帶寬被單個(gè)或少數(shù)用戶占用,影響其他用戶的訪問體驗(yàn)。通過實(shí)現(xiàn)文件下載的限速,可以平衡帶寬資源的使用,確保所有用戶都有良好的下載體驗(yàn)。

實(shí)現(xiàn)思路

為了實(shí)現(xiàn)文件下載的限速,我們需要以下幾個(gè)關(guān)鍵步驟:

  • 創(chuàng)建一個(gè)工具類,用于限制下載速率。
  • 在控制器中使用該工具類處理文件下載請(qǐng)求。
  • 使用StreamingResponseBody實(shí)現(xiàn)流式響應(yīng),確保大文件可以逐步傳輸。

代碼實(shí)現(xiàn)

步驟1:創(chuàng)建限速工具類

首先,我們創(chuàng)建一個(gè)限速工具類RateLimiter,該類包含一個(gè)方法limitDownloadSpeed,用于限制下載速率。

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @desc: 文件工具類
 * @author: shy
 * @date: 2024/06/28 11:27
 */
public class FileUtil {

    private static final int BUFFER_SIZE = 1024;

    /**
     * 文件下載限速
     *
     * @param in             輸入流
     * @param out            輸出流
     * @param bytesPerSecond 每秒允許下載的字節(jié)數(shù)
     * @throws IOException
     */
    public static void limitDownloadSpeed(InputStream in, OutputStream out, int bytesPerSecond) throws IOException {
        byte[] buffer = new byte[BUFFER_SIZE];
        int bytesRead;
        long bytesSent = 0;
        long startTime = System.currentTimeMillis();
        try {
            while ((bytesRead = in.read(buffer)) != -1) {
                // 將數(shù)據(jù)寫入輸出流
                out.write(buffer, 0, bytesRead);
                bytesSent += bytesRead;

                if (bytesSent >= bytesPerSecond) {
                    long elapsedTime = System.currentTimeMillis() - startTime;
                    if (elapsedTime < 1000) {
                        // 如果時(shí)間少于1秒,則休眠剩余時(shí)間
                        Thread.sleep(1000 - elapsedTime);
                    }
                    // 重置已發(fā)送字節(jié)計(jì)數(shù)和開始時(shí)間
                    bytesSent = 0;
                    startTime = System.currentTimeMillis();
                }
            }
        } catch (InterruptedException e) {
            // 恢復(fù)線程的中斷狀態(tài)
            Thread.currentThread().interrupt();
            throw new IOException("Thread was interrupted", e);
        }
    }
}

解釋

  • BUFFER_SIZE:定義緩沖區(qū)大小。
  • limitDownloadSpeed:通過try-with-resources管理InputStream,根據(jù)設(shè)定的速率讀取數(shù)據(jù)并寫入輸出流,控制傳輸速率。

步驟2:修改文件下載控制器

接下來,我們?cè)诳刂破髦惺褂?code>StreamingResponseBody來實(shí)現(xiàn)文件下載,并調(diào)用限速工具類的方法。

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import com.shy.admin.common.annotation.WithoutLogin;
import com.shy.common.utils.FileUtil;

/**
 * @desc: 文件下載Controller
 * @author: shy
 * @date: 2024/06/28 10:48
 */
@RestController
@RequestMapping("/file")
public class FileController {

    // 每秒允許下載的字節(jié)數(shù)(例如100KB/s)
    private static final int BYTES_PER_SECOND = 1024 * 100; 

    @WithoutLogin
    @GetMapping("/download/{filename}")
    public ResponseEntity<StreamingResponseBody> downloadFile(@PathVariable String filename) {
        // 獲取要下載的文件
        File file = new File("D:\\tools\\" + filename);
        // 使用 StreamingResponseBody 實(shí)現(xiàn)流式響應(yīng)體
        StreamingResponseBody responseBody = outputStream -> {
            try (InputStream inputStream = Files.newInputStream(file.toPath())) {
                // 調(diào)用限速方法
                FileUtil.limitDownloadSpeed(inputStream, outputStream, BYTES_PER_SECOND);
            }
        };
        // 返回 ResponseEntity,包含響應(yīng)頭和流式響應(yīng)體
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + file.getName())
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .contentLength(file.length())
                .body(responseBody);
    }
}

解釋

  • StreamingResponseBody:實(shí)現(xiàn)流式響應(yīng)體,用于處理大文件的逐步傳輸。
  • responseBody:通過lambda表達(dá)式實(shí)現(xiàn)StreamingResponseBodywriteTo方法,在方法中使用try-with-resources管理InputStream,并調(diào)用RateLimiter的方法實(shí)現(xiàn)限速。

工作流程

  1. 請(qǐng)求處理:當(dāng)客戶端發(fā)送下載請(qǐng)求時(shí),Spring 調(diào)用控制器方法downloadFile。
  2. 創(chuàng)建 StreamingResponseBody:控制器方法創(chuàng)建StreamingResponseBody實(shí)例。
  3. 返回 ResponseEntity:控制器方法返回包含StreamingResponseBodyResponseEntity,并設(shè)置適當(dāng)?shù)捻憫?yīng)頭(如Content-DispositionContent-Type)。
  4. 調(diào)用 writeTo 方法:Spring 在準(zhǔn)備向客戶端發(fā)送響應(yīng)時(shí),調(diào)用StreamingResponseBodywriteTo方法,并傳入與客戶端連接的OutputStream。
  5. 寫入數(shù)據(jù)writeTo方法中,從文件輸入流讀取數(shù)據(jù),并通過RateLimiter方法將數(shù)據(jù)寫入OutputStream,同時(shí)控制傳輸速率。

總結(jié)

通過以上步驟,我們成功在SpringBoot項(xiàng)目中實(shí)現(xiàn)了文件下載的限速功能。核心思路是通過一個(gè)限速工具類控制數(shù)據(jù)傳輸速率,并使用StreamingResponseBody實(shí)現(xiàn)流式響應(yīng),確保大文件可以逐步傳輸。這種設(shè)計(jì)既能有效控制帶寬資源的使用,又能提供良好的用戶下載體驗(yàn)。

以上就是SpringBoot實(shí)現(xiàn)文件下載的限速功能的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot文件下載限速的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java管道piped輸入流與輸出流應(yīng)用場(chǎng)景案例分析

    java管道piped輸入流與輸出流應(yīng)用場(chǎng)景案例分析

    這篇文章主要介紹了java管道流PipedInputStream與PipedOutputStream(輸入流與輸出流)的應(yīng)用場(chǎng)景案例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • Java基礎(chǔ)學(xué)習(xí)之接口詳解

    Java基礎(chǔ)學(xué)習(xí)之接口詳解

    接口,是Java語言中一種引用類型,是方法的集合,如果說類的內(nèi)部封裝了成員變量、構(gòu)造方法和成員方法,那么接口的內(nèi)部主要就是封裝了方法。本文通過一些示例詳細(xì)為大家展示了接口的使用,需要的可以參考一下
    2022-10-10
  • 使用WebUploader實(shí)現(xiàn)上傳文件功能(一)

    使用WebUploader實(shí)現(xiàn)上傳文件功能(一)

    這篇文章主要為大家詳細(xì)介紹了使用WebUploader實(shí)現(xiàn)上傳文件功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • MyBatis 核心配置文件及映射文件詳解

    MyBatis 核心配置文件及映射文件詳解

    MyBatis是支持定制化SQL、存儲(chǔ)過程以及高級(jí)映射的優(yōu)秀的持久層框架,本文重點(diǎn)介紹MyBatis 核心配置文件及映射文件,需要的朋友可以參考下
    2023-01-01
  • Java中IP段轉(zhuǎn)CIDR的原理與實(shí)現(xiàn)詳解

    Java中IP段轉(zhuǎn)CIDR的原理與實(shí)現(xiàn)詳解

    CIDR表示的是無類別域間路由,通常形式是IP地址后跟一個(gè)斜杠和數(shù)字,這篇文章主要為大家介紹了如何使用Java實(shí)現(xiàn)IP段轉(zhuǎn)CIDR,需要的可以了解下
    2025-03-03
  • Java超詳細(xì)大文件分片上傳代碼

    Java超詳細(xì)大文件分片上傳代碼

    文件上傳是一個(gè)很常見的功能。在項(xiàng)目開發(fā)過程中,我們通常都會(huì)使用一些成熟的上傳組件來實(shí)現(xiàn)對(duì)應(yīng)的功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧<BR>
    2022-06-06
  • springboot框架中如何整合mybatis框架思路詳解

    springboot框架中如何整合mybatis框架思路詳解

    這篇文章主要介紹了springboot框架中如何整合mybatis框架,本文通過示例圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • idea文件被鎖無法更改問題

    idea文件被鎖無法更改問題

    這篇文章主要介紹了idea文件被鎖無法更改問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • java反射之方法反射的基本操作方法

    java反射之方法反射的基本操作方法

    下面小編就為大家?guī)硪黄猨ava反射之方法反射的基本操作方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • Java?SpEL表達(dá)式注入入門學(xué)習(xí)示例教程

    Java?SpEL表達(dá)式注入入門學(xué)習(xí)示例教程

    SpEL是Spring框架特有的表達(dá)式語言,SpEL注入是Java Web題最常見的考點(diǎn)之一,因?yàn)樗壿嬊逦?利用方式很像 PHP 的 eval,本文給大家介紹Java?SpEL表達(dá)式注入入門學(xué)習(xí)示例教程,感興趣的朋友跟隨小編一起看看吧
    2025-12-12

最新評(píng)論

灵石县| 田东县| 本溪市| 兴仁县| 安乡县| 桦甸市| 广南县| 尼木县| 余江县| 噶尔县| 调兵山市| 华亭县| 武陟县| 马边| 武义县| 桑日县| 长海县| 澄城县| 西充县| 仪陇县| 巴彦淖尔市| 阿城市| 平阴县| 东明县| 原阳县| 垫江县| 沙坪坝区| 景宁| 辽宁省| 太保市| 涞水县| 安塞县| 淮南市| 正宁县| 化州市| 霸州市| 会泽县| 广宁县| 太白县| 高雄县| 阿巴嘎旗|