Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 resources use FileInputStream (which I can't use).

Anyone know how I can accomplish this?

like image 283
Corey Avatar asked Jan 13 '11 21:01

Corey


1 Answers

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();
like image 196
Ralph Avatar answered Sep 21 '22 00:09

Ralph