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

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

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

前言

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

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

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

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

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

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

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

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

/**
 * @desc: 文件工具類(lèi)
 * @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ù)寫(xiě)入輸出流
                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ù)和開(kāi)始時(shí)間
                    bytesSent = 0;
                    startTime = System.currentTimeMillis();
                }
            }
        } catch (InterruptedException e) {
            // 恢復(fù)線(xiàn)程的中斷狀態(tài)
            Thread.currentThread().interrupt();
            throw new IOException("Thread was interrupted", e);
        }
    }
}

解釋

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

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

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

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:通過(guò)lambda表達(dá)式實(shí)現(xiàn)StreamingResponseBodywriteTo方法,在方法中使用try-with-resources管理InputStream,并調(diào)用RateLimiter的方法實(shí)現(xiàn)限速。

工作流程

  1. 請(qǐng)求處理:當(dāng)客戶(hù)端發(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)備向客戶(hù)端發(fā)送響應(yīng)時(shí),調(diào)用StreamingResponseBodywriteTo方法,并傳入與客戶(hù)端連接的OutputStream。
  5. 寫(xiě)入數(shù)據(jù)writeTo方法中,從文件輸入流讀取數(shù)據(jù),并通過(guò)RateLimiter方法將數(shù)據(jù)寫(xiě)入OutputStream,同時(shí)控制傳輸速率。

總結(jié)

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

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

相關(guān)文章

  • SpringBoot項(xiàng)目的配置文件中設(shè)置server.port不生效問(wèn)題

    SpringBoot項(xiàng)目的配置文件中設(shè)置server.port不生效問(wèn)題

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

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

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

    IDEA?maven項(xiàng)目依賴(lài)無(wú)法解析問(wèn)題

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

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

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

    基于log4j2.properties踩坑與填坑

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

    java常見(jiàn)的字符串拼接方式總結(jié)

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

    Java數(shù)據(jù)結(jié)構(gòu)之線(xiàn)段樹(shù)中的懶操作詳解

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

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

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

    spring源碼下載、編譯、debug的詳細(xì)教程

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

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

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

最新評(píng)論