Skip to content

Software Development at Program Tom LTD

Place for coding, programming, development and software in general.

Menu
  • Blog
  • PDF Booklets
  • Dev Utils & Content
  • Java Spring Boot Or Web Apps
  • English
    • български
    • English
    • Español
    • Português
    • हिन्दी
    • Русский
    • Deutsch
    • Français
    • Italiano
    • العربية
  • About Us
  • Flutter Apps
Menu
IOException: Stream Closed - when having ResponseEntity - a file

IOException: Stream Closed – when having ResponseEntity – a file

Posted on January 18, 2025 by Toma Velev

The error java.io.IOException: Stream Closed indicates that the InputStream passed to the InputStreamResource has already been closed before it is read by the Spring framework to create the response.

Use Case

The use case where you may need to encounter this error is file download from Spring Boot App. Writing down bytes loaded in memory – as a Base64 String may be an option – only if you know that the files will not be very big. For anything above one megabyte the proper way to handle it is with Stream – lazy – without loading it all to memory.

Here are common reasons this might happen:

1. The InputStream is closed before being used

  • If you have explicitly closed the InputStream somewhere in your code after wrapping it in the InputStreamResource, this will result in the Stream Closed exception when the framework tries to read it.

Example issue:

InputStream inputStream = new FileInputStream(file);
inputStream.close(); // Closing the stream prematurely
return ResponseEntity.ok()
      .body(new InputStreamResource(inputStream)); // Fails because the stream is closed

2. InputStream is auto-closed

  • If the InputStream was opened in a try-with-resources block, it will be automatically closed at the end of the block before the ResponseEntity can use it.

Example issue:

try (InputStream inputStream = new FileInputStream(file)) {
    return ResponseEntity.ok()
          .body(new InputStreamResource(inputStream)); // Stream is closed when try block ends
}

3. Reusing a closed InputStream

  • If the InputStream is read somewhere else before being passed to the InputStreamResource, the stream pointer reaches the end of the stream, and the stream might also be closed by the code consuming it.

Example issue:

InputStream inputStream = new FileInputStream(file);
byte[] buffer = inputStream.readAllBytes(); // Consumes the stream
// Passing the same stream to InputStreamResource will fail
return ResponseEntity.ok()
      .body(new InputStreamResource(inputStream)); // Stream already consumed or closed

Solutions

  1. Ensure the InputStream is open and valid
    • Make sure the InputStream you pass to InputStreamResource is not closed or consumed beforehand.

    Correct Code:

    InputStream inputStream = new FileInputStream(file);
    return ResponseEntity.ok()
          .contentType(MediaType.APPLICATION_OCTET_STREAM)
          .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
          .body(new InputStreamResource(inputStream));
    
  2. Avoid try-with-resources for InputStream
    • Do not use try-with-resources if you plan to pass the InputStream to InputStreamResource, as it closes the stream automatically.
  3. Use a fresh InputStream for each request
    • If you are reading from a file, create a new FileInputStream for every request.

    Example:

    return ResponseEntity.ok()
          .contentType(MediaType.APPLICATION_OCTET_STREAM)
          .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
          .body(new InputStreamResource(new FileInputStream(file)));
    
  4. Buffered InputStream for reusable streams
    • If the stream is large and you want better performance, consider wrapping it in a BufferedInputStream to prevent accidental closure or reading.
  5. Debugging Tip
    • Add logging or debugging to check if the InputStream is being consumed or closed elsewhere in your code.

Let me know if you’d like help analyzing your specific code structure!

Will Spring close the stream?

Yes, Spring will close the InputStream when it is used in a ResponseEntity with InputStreamResource. This is because Spring considers it the owner of the stream and ensures proper resource cleanup after the response is written.

Check out my Spring Boot Web Apps: https://programtom.com/dev/product-category/technologies/spring-boot-framework/?orderby=date-desc

  • What are ways to Optimize the backend endpoints in Spring Boot
  • Flutter image flickers
  • Could a Flutter App save a Flag even after uninstall
  • Could iOS flutter app logs be viewed while running in release mode – started after previous closed state
  • 6 Addictive Mobile Game Ideas Inspired by Flappy Bird’s Simplicity

Categories

  • Apps (20)
  • ChatGPT (19)
  • Choosing a Framework (38)
  • Flutter (206)
  • Graphical User Interface (13)
  • Marketing (114)
  • Software Development (270)
  • Spring (43)
  • StartUp (21)
  • Uncategorized (4)
  • Uncategorized (15)
  • Vaadin (14)

Tags

Algorithms (9) crypto (29) flutterdev (39) General (86) Java (7) QR & Bar Codes (3) Software Dev Choices (33) Spring Boot (1) standards (1) Theme (3) User Authentication & Authorization (9) User Experience (10) Utilities (19) WordPress (11)

Product categories

  • All Technologies (83)
    • Flutter Apps (23)
    • GPT (4)
    • Java (38)
    • Native Android (3)
    • PHP (9)
    • Spring (Boot) / Quarkus (35)
    • Utils (15)
    • Vaadin 24+ (27)
    • Vaadin 8 (1)
  • Apps (18)
    • Employees DB (1)
    • Notes (6)
    • Personal Budget (1)
    • Recipes Book (1)
    • Stuff Organizer (1)
    • To-Do (2)
  • PDF Books (3)
  • Source Code Generators (8)

Recent Posts

  • What are ways to Optimize the backend endpoints in Spring Boot
  • Flutter image flickers
  • Could a Flutter App save a Flag even after uninstall
  • Could iOS flutter app logs be viewed while running in release mode – started after previous closed state
  • 6 Addictive Mobile Game Ideas Inspired by Flappy Bird’s Simplicity

Post Categories

  • Apps (20)
  • ChatGPT (19)
  • Choosing a Framework (38)
  • Flutter (206)
  • Graphical User Interface (13)
  • Marketing (114)
  • Software Development (270)
  • Spring (43)
  • StartUp (21)
  • Uncategorized (4)
  • Uncategorized (15)
  • Vaadin (14)