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.