欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

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

實現(xiàn)思路

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

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

代碼實現(xiàn)

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

首先,我們創(chuàng)建一個限速工具類RateLimiter,該類包含一個方法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) {
                        // 如果時間少于1秒,則休眠剩余時間
                        Thread.sleep(1000 - elapsedTime);
                    }
                    // 重置已發(fā)送字節(jié)計數(shù)和開始時間
                    bytesSent = 0;
                    startTime = System.currentTimeMillis();
                }
            }
        } catch (InterruptedException e) {
            // 恢復線程的中斷狀態(tài)
            Thread.currentThread().interrupt();
            throw new IOException("Thread was interrupted", e);
        }
    }
}

解釋

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

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

接下來,我們在控制器中使用StreamingResponseBody來實現(xiàn)文件下載,并調用限速工具類的方法。

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 實現(xiàn)流式響應體
        StreamingResponseBody responseBody = outputStream -> {
            try (InputStream inputStream = Files.newInputStream(file.toPath())) {
                // 調用限速方法
                FileUtil.limitDownloadSpeed(inputStream, outputStream, BYTES_PER_SECOND);
            }
        };
        // 返回 ResponseEntity,包含響應頭和流式響應體
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + file.getName())
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .contentLength(file.length())
                .body(responseBody);
    }
}

解釋

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

工作流程

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

總結

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

以上就是SpringBoot實現(xiàn)文件下載的限速功能的詳細內容,更多關于SpringBoot文件下載限速的資料請關注腳本之家其它相關文章!

相關文章

  • SpringBoot項目的配置文件中設置server.port不生效問題

    SpringBoot項目的配置文件中設置server.port不生效問題

    這篇文章主要介紹了SpringBoot項目的配置文件中設置server.port不生效問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Java中@valid和@Validated注解的使用詳解

    Java中@valid和@Validated注解的使用詳解

    這篇文章主要介紹了Java中@valid和@Validated注解的使用詳解,@Validated可以用在類型、方法和方法參數(shù)上,但是不能用在成員屬性(字段)上,不支持嵌套檢測,@Valid可以用在方法、構造函數(shù)、方法參數(shù)和成員屬性(字段)上,支持嵌套檢測,需要的朋友可以參考下
    2024-01-01
  • IDEA?maven項目依賴無法解析問題

    IDEA?maven項目依賴無法解析問題

    這篇文章主要介紹了IDEA?maven項目依賴無法解析問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • JavaWeb實現(xiàn)學生信息管理系統(tǒng)(2)

    JavaWeb實現(xiàn)學生信息管理系統(tǒng)(2)

    這篇文章主要介紹了JavaWeb實現(xiàn)學生信息管理系統(tǒng)的第二篇,實現(xiàn)學生管理系統(tǒng)的查找和添加功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 基于log4j2.properties踩坑與填坑

    基于log4j2.properties踩坑與填坑

    這篇文章主要介紹了log4j2.properties踩坑與填坑方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java常見的字符串拼接方式總結

    java常見的字符串拼接方式總結

    這篇文章主要為大家詳細介紹了java中常見的字符串拼接方式,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-09-09
  • Java數(shù)據(jù)結構之線段樹中的懶操作詳解

    Java數(shù)據(jù)結構之線段樹中的懶操作詳解

    對于線段樹,若要求對區(qū)間中的所有點都進行更新,可以引入懶操作。懶操作包括區(qū)間更新和區(qū)間查詢操作。本文將通過一個示例和大家詳細聊聊線段樹中的懶操作,需要的可以參考一下
    2022-10-10
  • springboot時間格式化的五種方法總結(解決后端傳給前端的時間顯示不一致)

    springboot時間格式化的五種方法總結(解決后端傳給前端的時間顯示不一致)

    這篇文章主要給大家介紹了關于springboot時間格式化的五種方法,文中介紹的方法解決了后端傳給前端的時間顯示不一致,文中通過圖文以及代碼介紹的非常詳細,需要的朋友可以參考下
    2024-01-01
  • spring源碼下載、編譯、debug的詳細教程

    spring源碼下載、編譯、debug的詳細教程

    這篇文章主要介紹了spring源碼下載、編譯、debug的詳細教程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Java生成日期時間存入Mysql數(shù)據(jù)庫的實現(xiàn)方法

    Java生成日期時間存入Mysql數(shù)據(jù)庫的實現(xiàn)方法

    本文主要介紹了Java生成日期時間存入Mysql數(shù)據(jù)庫的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評論