Yes, you can do it better. Instead of manipulating physical data on your hard disk, you can do it totally on memory.
As @Olivier mentioned in the comment section, you need an output stream.
For example, you have a controller which returns a .txt file as a zip:
@PostMapping(value = "/zip", produces = "application/zip") public ResponseEntity<StreamingResponseBody> zip() { return ResponseEntity .ok()// .header("Content-Disposition", "attachment; filename=\"my.zip\"")// .body(out -> generateZip(out)); }
To generate a zip file on the given OutPutStream in response by in-memory data:
public void generateZip(OutputStream outPutStream) { String data = "Test data \n123\n456"; String fileNameInZip = "abc.txt"; try (ZipOutputStream zipOutput = new ZipOutputStream(outPutStream)) { ZipEntry zipEntry = new ZipEntry(fileNameInZip); zos.putNextEntry(zipEntry); ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes()); // one line, able to handle large size? //zos.write(bais.readAllBytes()); // play safe byte[] buffer = new byte[1024]; int len; while ((len = bais.read(buffer)) > 0) { zos.write(buffer, 0, len); } zos.closeEntry(); } }
Of course, this generateZip function is just an example of demonstrating the zipping operation and writing it on the output stream.
You need to implement your logic in generateZip.
You can read more about zip operations such as multiple files in one file zipping, etc. here.
ZipOutputStreamtag gives the answer to your question. That class doesn't use files, only streams, so you can do everything in memory.