Master Large File Streaming in Spring Boot 3: Upload & Download Techniques

This article explains how to efficiently handle massive file uploads and downloads in Spring Boot 3 using traditional blocking I/O, reactive WebFlux streams, and proper configuration to keep memory usage low while maintaining high performance.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master Large File Streaming in Spring Boot 3: Upload & Download Techniques

Introduction

In web applications, uploading and downloading large files is a tricky challenge. Spring Boot simplifies this with built‑in streaming mechanisms such as InputStreamResource and OutputStream, which keep memory consumption low when processing big files.

Large File Upload Streaming

Spring Boot supports multipart file upload by default, but loading an entire large file into memory can cause performance problems. Using a blocking InputStream to read the file in small chunks avoids high memory usage.

@PostMapping("")
public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
    Path filePath = Paths.get("d:/upload/" + file.getOriginalFilename());
    try (InputStream inputStream = file.getInputStream();
         OutputStream outputStream = Files.newOutputStream(filePath, StandardOpenOption.CREATE)) {
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
    } catch (IOException e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("文件上传错误: " + e.getMessage());
    }
    return ResponseEntity.ok("文件上传成功");
}

Reading the file in 8 KB blocks prevents excessive memory consumption, and the try‑with‑resources statement automatically closes streams.

Reactive (WebFlux) Upload

Spring WebFlux provides a non‑blocking way to handle uploads using Flux<DataBuffer>. The file is processed as a continuous data stream, which is ideal for cloud environments or concurrent large‑file uploads.

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

If both spring-boot-starter-web and spring-boot-starter-webflux are on the classpath, set the application type to reactive:

spring:
  main:
    web-application-type: reactive

Multipart size limits can be configured as follows:

spring:
  servlet:
    multipart:
      max-file-size: 100MB
      max-request-size: 200MB

Upload Summary

Simple upload: MultipartFile works for small files but may not be optimal for large ones.

Memory‑efficient upload: Using InputStream processes files in chunks.

Reactive approach: Flux<DataBuffer> in WebFlux offers the best performance for concurrent large uploads.

Large File Download Streaming

Downloading huge files without loading them entirely into memory can be achieved with InputStreamResource, which streams data to the client in small chunks.

@GetMapping("/stream")
public ResponseEntity<InputStreamResource> downloadFile() throws IOException {
    Path filePath = Paths.get("d:/devsoft/Chat2DB-Setup-1.0.11.exe");
    InputStreamResource resource = new InputStreamResource(Files.newInputStream(filePath));
    return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=Chat2DB-Setup-1.0.11.exe")
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(resource);
}

The Files.newInputStream method opens a stream without loading the whole file, and the resource supplies data blocks as they become available.

OutputStream Download

Using OutputStream gives finer control over buffer size and transmission speed.

@GetMapping("/os")
public void downloadFileStream(HttpServletResponse response) throws IOException {
    Path filePath = Paths.get("d:/devsoft/Chat2DB-Setup-1.0.11.exe");
    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment; filename=Chat2DB-Setup-1.0.11.exe");
    try (OutputStream out = response.getOutputStream();
         InputStream in = Files.newInputStream(filePath)) {
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) != -1) {
            out.write(buffer, 0, bytesRead);
        }
    }
}

Reactive (WebFlux) Download

WebFlux can serve large files non‑blocking by streaming DataBuffer objects.

@GetMapping(value = "/reactive", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public Mono<Void> downloadFileReactive(ServerHttpResponse response) {
    Path filePath = Paths.get("d:/devsoft/Chat2DB-Setup-1.0.11.exe");
    Flux<DataBuffer> fileStream = DataBufferUtils.read(filePath, new DefaultDataBufferFactory(), 8192);
    response.getHeaders().add("Content-Disposition", "attachment; filename=Chat2DB-Setup-1.0.11.exe");
    return response.writeWith(fileStream);
}

This method uses Flux<DataBuffer> to transmit 8 KB chunks without blocking threads, making it ideal for high‑concurrency scenarios such as media streaming or cloud file storage services.

Download Summary

InputStreamResource: Simple, low‑memory streaming for standard downloads.

OutputStream: Allows custom buffer control for performance‑critical cases.

WebFlux (Flux<DataBuffer>): Best for concurrent large‑file downloads in reactive applications.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Streamingfile uploadWebFluxInputStreamDataBuffer
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.