成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

挑戰(zhàn)大文件傳輸極限!基于兩種技術(shù)棧的 Spring Boot 流式處理實戰(zhàn)

開發(fā) 前端
對于需要傳輸大文件的系統(tǒng)而言,Spring Boot 提供了“阻塞”與“響應(yīng)式”兩種武器——前者成熟穩(wěn)定,適合常規(guī)系統(tǒng);后者輕盈高效,天生適配現(xiàn)代云架構(gòu)與高并發(fā)負(fù)載。

在現(xiàn)代企業(yè)級 Web 系統(tǒng)中,上傳或下載大于 100MB 的文件早已成為標(biāo)配,如上傳日志、視頻、數(shù)據(jù)庫備份,或從服務(wù)器分發(fā)大文件。但傳統(tǒng)做法通常會將整個文件加載到內(nèi)存中處理,這樣做的結(jié)果是:

  • 內(nèi)存消耗大;
  • 性能下降;
  • 并發(fā)能力差;
  • 大概率觸發(fā) OOM。

Spring Boot 針對這一挑戰(zhàn),提供了兩種不同的流式處理技術(shù)路徑:

  1. 基于傳統(tǒng) Servlet 架構(gòu)的阻塞式流式處理(適合大多數(shù)場景);
  2. 基于 WebFlux 響應(yīng)式模型的非阻塞處理(適合高并發(fā)環(huán)境、云平臺)。

本篇文章將從上傳與下載兩個方面,詳細(xì)剖析這兩種架構(gòu)下的處理方式,并輔以前端 Thymeleaf + Bootstrap 頁面整合,構(gòu)建可直接實戰(zhàn)部署的文件服務(wù)能力。

后端實現(xiàn)

文件上傳:流式處理雙架構(gòu)對比

傳統(tǒng)阻塞模型上傳(基于 Servlet 的 InputStream)

  • 使用 MultipartFile 獲取上傳內(nèi)容;
  • 通過 InputStream 讀取上傳數(shù)據(jù)并寫入 OutputStream;
  • 實現(xiàn)方式清晰,適合文件不大的常規(guī)業(yè)務(wù)系統(tǒng)。

路徑:src/main/java/com/icoderoad/controller/FileUploadController.java

package com.icoderoad.controller;


import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import java.io.*;
import java.nio.file.*;


@RestController
@RequestMapping("/file")
public class FileUploadController {


    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        Path path = Paths.get("/data/uploads/", file.getOriginalFilename());
        try (InputStream in = file.getInputStream();
             OutputStream out = Files.newOutputStream(path, StandardOpenOption.CREATE)) {


            byte[] buffer = new byte[8192]; // 分塊讀取,防止內(nèi)存暴漲
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                                 .body("上傳失敗:" + e.getMessage());
        }
        return ResponseEntity.ok("上傳成功!");
    }
}

響應(yīng)式模型上傳(基于 WebFlux 的 Flux)

  • 使用 Flux<DataBuffer> 讀取上傳流;
  • 每塊數(shù)據(jù)到達(dá)就立即寫入磁盤;
  • 完全非阻塞,適合海量并發(fā)上傳。

路徑:src/main/java/com/icoderoad/webflux/FileReactiveUploadHandler.java

package com.icoderoad.webflux;


import org.springframework.core.io.buffer.*;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;


import java.nio.file.*;


@RestController
@RequestMapping("/file")
public class FileReactiveUploadHandler {


    @PostMapping(value = "/upload/reactive", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Mono<Void> uploadReactive(@RequestPart("file") Flux<DataBuffer> fileBuffer,
                                     @RequestPart("fileName") String fileName) {
        Path path = Paths.get("/data/uploads/", fileName);
        return DataBufferUtils.write(fileBuffer, path, StandardOpenOption.CREATE).then();
    }
}

 注意:若你的工程中同時引入了 spring-boot-starter-web 和 spring-boot-starter-webflux,需添加如下配置防止沖突:

spring:
  main:
    web-application-type: reactive

文件下載:流式返回雙架構(gòu)詳解

Servlet 模型下載(InputStreamResource 或 OutputStream)

方式一:InputStreamResource 下載(推薦)

 路徑:src/main/java/com/icoderoad/controller/FileDownloadController.java

@GetMapping("/download")
public ResponseEntity<InputStreamResource> download() throws IOException {
    Path path = Paths.get("/data/packages/demo-installer.exe");
    InputStreamResource resource = new InputStreamResource(Files.newInputStream(path));


    return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=demo-installer.exe")
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(resource);
}

方式二:OutputStream 手動寫入(適合控制更細(xì)粒度)

@GetMapping("/download/stream")
public void downloadStream(HttpServletResponse response) throws IOException {
    Path path = Paths.get("/data/packages/demo-installer.exe");
    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment; filename=demo-installer.exe");


    try (InputStream in = Files.newInputStream(path);
         OutputStream out = response.getOutputStream()) {
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) != -1) {
            out.write(buffer, 0, bytesRead);
        }
    }
}

WebFlux 響應(yīng)式下載(Flux)

路徑:src/main/java/com/icoderoad/webflux/FileReactiveDownloadHandler.java

@GetMapping(value = "/download/reactive", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public Mono<Void> downloadReactive(ServerHttpResponse response) {
    Path filePath = Paths.get("/data/packages/demo-installer.exe");
    Flux<DataBuffer> fileStream = DataBufferUtils.read(filePath, new DefaultDataBufferFactory(), 8192);


    response.getHeaders().add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=demo-installer.exe");
    return response.writeWith(fileStream);
}

前端頁面集成:Thymeleaf + Bootstrap 實現(xiàn)上傳下載

上傳頁面:src/main/resources/templates/upload.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>大文件上傳 - Spring Boot 流式處理</title>
    <meta charset="UTF-8">
    <link  rel="stylesheet">
</head>
<body class="bg-light">


<div class="container mt-5">
    <div class="row justify-content-center">
        <div class="col-md-6">
            <div class="card shadow-sm">
                <div class="card-header bg-primary text-white text-center">
                    <h4>大文件上傳</h4>
                </div>
                <div class="card-body">
                    <form id="uploadForm" enctype="multipart/form-data">
                        <div class="mb-3">
                            <label for="file" class="form-label">選擇要上傳的文件</label>
                            <input type="file" class="form-control" name="file" id="file" required>
                        </div>
                        <button type="submit" class="btn btn-success w-100">開始上傳</button>
                    </form>
                    <div id="uploadResult" class="mt-3 alert d-none" role="alert"></div>
                </div>
            </div>
        </div>
    </div>
</div>


<script>
    const form = document.getElementById("uploadForm");
    const resultBox = document.getElementById("uploadResult");


    form.addEventListener("submit", function (e) {
        e.preventDefault();
        const formData = new FormData(form);
        resultBox.className = "mt-3 alert alert-info";
        resultBox.innerText = "上傳中,請稍候...";


        fetch("/file/upload", {
            method: "POST",
            body: formData
        })
        .then(response => response.text())
        .then(message => {
            resultBox.className = "mt-3 alert alert-success";
            resultBox.innerText = message;
        })
        .catch(error => {
            resultBox.className = "mt-3 alert alert-danger";
            resultBox.innerText = "上傳失敗:" + error.message;
        });
    });
</script>


</body>
</html>

下載頁面:src/main/resources/templates/download.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>大文件下載 - Spring Boot 流式處理</title>
    <meta charset="UTF-8">
    <link  rel="stylesheet">
</head>
<body class="bg-light">


<div class="container mt-5">
    <div class="row justify-content-center">
        <div class="col-md-6 text-center">
            <div class="card shadow-sm">
                <div class="card-header bg-success text-white">
                    <h4>下載大文件</h4>
                </div>
                <div class="card-body">
                    <p class="lead">點擊按鈕即可開始下載服務(wù)端的大文件</p>
                    <a href="/file/download" class="btn btn-primary btn-lg w-100">
                        下載文件(阻塞式)
                    </a>
                    <a href="/file/download/reactive" class="btn btn-outline-success btn-lg w-100 mt-3">
                        下載文件(響應(yīng)式)
                    </a>
                </div>
            </div>
        </div>
    </div>
</div>


</body>
</html>

技術(shù)架構(gòu)比較與適用建議

類型

技術(shù)方案

優(yōu)勢

適用場景

上傳

MultipartFile

簡單易用

小文件、表單上傳

上傳

InputStream

內(nèi)存控制優(yōu)

中大型文件、低并發(fā)場景

上傳

Flux

非阻塞、內(nèi)存占用極低

高并發(fā)上傳服務(wù)、云函數(shù)

下載

InputStreamResource

快速、穩(wěn)定

一般大文件下載

下載

OutputStream

緩沖可調(diào)、可控性強(qiáng)

定制化響應(yīng)、流控制需求

下載

Flux

非阻塞高性能

視頻流、云平臺大規(guī)模文件分發(fā)

結(jié)語:選擇合適技術(shù)棧,跑得更快更遠(yuǎn)

對于需要傳輸大文件的系統(tǒng)而言,Spring Boot 提供了“阻塞”與“響應(yīng)式”兩種武器——前者成熟穩(wěn)定,適合常規(guī)系統(tǒng);后者輕盈高效,天生適配現(xiàn)代云架構(gòu)與高并發(fā)負(fù)載。

通過合理配置與實現(xiàn):

  • 你可以輕松上傳/下載 GB 級別的文件;
  • 內(nèi)存占用控制在最小;
  • 性能瓶頸被徹底打破。
責(zé)任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2020-06-18 08:18:35

密碼加密安全

2013-05-29 09:59:20

Java-RMI遠(yuǎn)程調(diào)用

2013-12-20 11:05:13

IBM大數(shù)據(jù)Aspera

2021-01-25 14:10:49

Spring BootVueJava

2014-04-28 09:29:36

2013-06-10 16:28:23

2010-04-28 16:18:19

負(fù)載均衡技術(shù)

2009-09-08 15:22:20

Spring依賴注入

2010-05-10 18:19:00

負(fù)載平衡技術(shù)

2009-06-23 18:18:13

SpringHibernate

2009-10-27 09:49:38

無線接入技術(shù)

2025-03-28 05:10:00

Spring上傳大文件

2009-06-15 15:02:48

Spring定時器

2011-03-30 20:49:55

上網(wǎng)行為管理文件傳輸網(wǎng)康科技

2023-05-31 19:10:31

2021-07-26 14:14:40

VRAI人工智能

2009-10-28 10:34:12

2020-11-23 17:25:37

鐳速聯(lián)合架構(gòu)存儲

2024-01-29 12:48:00

Jenkins監(jiān)控運維

2010-12-08 12:34:46

文件傳輸
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: av一区二区在线观看 | 亚洲国产成人精品久久久国产成人一区 | 久久高清国产 | 观看av| 精品久久一区二区 | 欧美激情国产精品 | 国产精品亚洲片在线播放 | 日本黄色免费片 | 免费午夜电影 | 成人影院在线 | 亚洲久久一区 | 久久精品69 | 精品无码久久久久久国产 | 本地毛片| 国产香蕉视频在线播放 | 亚洲第一在线 | 国产乱码精品一区二三赶尸艳谈 | 亚洲视频免费观看 | 91在线看片| www.9191 | 午夜成人在线视频 | 亚洲精品久久久久久久久久久久久 | 99精品一级欧美片免费播放 | 欧美亚洲免费 | 国产精品日产欧美久久久久 | 中文字字幕在线中文乱码范文 | 国产91丝袜在线播放 | 日韩影院在线 | 91一区二区三区 | 九九热最新地址 | 日韩视频精品 | 影音先锋成人资源 | 久久ww| 午夜性视频| 欧美亚洲国产日韩 | 草久久| 中文字幕在线精品 | 福利视频日韩 | 色婷婷久久 | 精品欧美黑人一区二区三区 | 国产中文字幕在线 |