BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ I/O and files

I/O and data

File upload and download

Uploads arrive as multipart form data and downloads are streams with a Content-Disposition header.

Learn these first

At a glance

Mental model

A mailroom: parcels arrive in a standard envelope, you check the label (name, size, type) before accepting, and when sending out you attach the right label so the recipient knows what is inside.

What happens, in order
  1. 1A controller parameter @RequestParam("file") MultipartFile file receives one uploaded file; file.getBytes(), getInputStream() and transferTo(path) read or store it
  2. 2For downloads, return ResponseEntity<Resource> with Content-Disposition: attachment; filename="report.pdf" and the right Content-TypeA Resource is streamed instead of loaded entirely into memory.
  3. 3Set limits (spring.servlet.multipart.max-file-size, max-request-size) so a huge upload fails fast with a clear error instead of filling the disk
  4. 4For large files, upload directly to object storage with a presigned URL so the bytes never pass through your service
Remember
Watch out
Using the client file name as the storage pathLoading big files fully into memoryNo size limitsTrusting the client content type
Example (highlighted lines explain it)
@PostMapping("/documents")public ResponseEntity<Void> upload(@RequestParam("file") MultipartFile file) throws IOException {    if (file.isEmpty() || file.getSize() > 10_000_000) {        return ResponseEntity.badRequest().build();    }    Path target = storage.resolve(UUID.randomUUID() + ".bin");    file.transferTo(target);    return ResponseEntity.created(URI.create("/documents/" + target.getFileName())).build();}
  1. line 2 uses MultipartFile, the core of File upload and download
  2. line 7 uses transferTo, the core of File upload and download
Read the full explanation (about 1 min)

Uploads arrive as multipart form data and downloads are streams with a Content-Disposition header. Both are classic places for security bugs, memory problems and wrong content types.

A mental model

A mailroom: parcels arrive in a standard envelope, you check the label (name, size, type) before accepting, and when sending out you attach the right label so the recipient knows what is inside.

How it works

A controller parameter @RequestParam("file") MultipartFile file receives one uploaded file; file.getBytes(), getInputStream() and transferTo(path) read or store it.

For downloads, return ResponseEntity<Resource> with Content-Disposition: attachment; filename="report.pdf" and the right Content-Type. A Resource is streamed instead of loaded entirely into memory.

Set limits (spring.servlet.multipart.max-file-size, max-request-size) so a huge upload fails fast with a clear error instead of filling the disk.

For large files, upload directly to object storage with a presigned URL so the bytes never pass through your service.

Going deeper

Never trust getOriginalFilename(). A name like ../../etc/passwd is a path traversal attack; generate your own storage name and keep the original only as metadata.

Check the real content type (magic bytes), size and extension against an allow-list; the type sent by the client is just a claim. Scan for malware if files are shared with other users.

getBytes() loads the whole file into the heap. Stream with getInputStream() and copy in chunks, and close streams in try-with-resources.

Under the hood

The container parses the multipart body into parts, keeping small ones in memory and spilling large ones to a temporary directory. MultipartFile is a thin wrapper over that part; the temp file is deleted after the request, so transferTo must be done inside the request.

Common mistakes

  • Using the client file name as the storage path.
  • Loading big files fully into memory.
  • No size limits.
  • Trusting the client content type.

How Unravel recognises it

When you paste code, Unravel looks for these signs of file upload and download. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is File upload and download?

Uploads arrive as multipart form data and downloads are streams with a Content-Disposition header. Both are classic places for security bugs, memory problems and wrong content types.

What are the most common mistakes with File upload and download?

Using the client file name as the storage path. Loading big files fully into memory. No size limits. Trusting the client content type.

How can I see File upload and download in real code?

Paste your own Java into Unravel and it will point out where file upload and download appears, explain how it works at the detail level you choose, and draw the flow of the code around it.