How to create ZIP file for a list of "virtual files" and output to httpservletresponse
My goal is to put multiple java.io.File objects into a zip file and print to HttpServletResponse for the user to download.
The files were created by the JAXB marshaller. It's a java.io.File object, but it's not actually on the file system (it's only in memory), so I can't create a FileInputStream.
All resources I've seen use the OutputStream to print zip file contents. But, all those开发者_Go百科 resources use FileInputStream (which I can't use).
Anyone know how I can accomplish this?
Have a look at the Apache Commons Compress library, it provides the functionality you need.
Of course "erickson" is right with his comment to your question. You will need the file content and not the java.io.File
object. In my example I assume that you have a method
byte[] getTheContentFormSomewhere(int fileNummer)
which returns the file content (in memory) for the fileNummer-th file. -- Of course this function is poor design, but it is only for illustration.
It should work a bit like this:
void compress(final OutputStream out) {
ZipOutputStream zipOutputStream = new ZipOutputStream(out);
zipOutputStream.setLevel(ZipOutputStream.STORED);
for(int i = 0; i < 10; i++) {
//of course you need the file content of the i-th file
byte[] oneFileContent = getTheContentFormSomewhere(i);
addOneFileToZipArchive(zipOutputStream, "file"+i+"."txt", oneFileContent);
}
zipOutputStream.close();
}
void addOneFileToZipArchive(final ZipOutputStream zipStream,
String fileName,
byte[] content) {
ZipArchiveEntry zipEntry = new ZipArchiveEntry(fileName);
zipStream.putNextEntry(zipEntry);
zipStream.write(pdfBytes);
zipStream.closeEntry();
}
Snipets of your http controller:
HttpServletResponse response
...
response.setContentType("application/zip");
response.addHeader("Content-Disposition", "attachment; filename=\"compress.zip\"");
response.addHeader("Content-Transfer-Encoding", "binary");
ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream();
compress(outputBuffer);
response.getOutputStream().write(outputBuffer.toByteArray());
response.getOutputStream().flush();
outputBuffer.close();
Turns out I'm an idiot :) The file that was being "created" was saving to invalid path and swallowing the exception, so I thought it was being "created" ok. When I tried to to instantiate a new FileInputStream, however, it complained that file didn't exist (rightly so). I had a brainfart and assumed that the java.io.File object actually contained file information in it somewhere. But as erickson pointed out, that was false.
Thanks Ralph for the code, I used it after I solved the invalid pathing issue.
My code:
ZipOutputStream out = new ZipOutputStream(response.getOutputStream());
byte[] buf = new byte[1024];
File file;
InputStream in;
// Loop through entities
for (TitleProductAccountApproval tpAccountApproval : tpAccountApprovals) {
// Generate the file
file = xmlManager.getXML(
tpAccountApproval.getTitleProduct().getTitleProductId(),
tpAccountApproval.getAccount().getAccountId(),
username);
// Write to zip file
in = new FileInputStream(file);
out.putNextEntry(new ZipEntry(file.getName()));
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.closeEntry();
in.close();
}
out.close();
精彩评论