tags:

views:

18

answers:

1

I'm trying ZIP a bundle of File's and return ZIP through a servlet. This works fine if I just have one file but when I try to add more it seems they are just being appended to the first ZipEntry and thus the zip archive gets corrupted.

private void writeZipResponse(HttpServletResponse response,
  List<File> bundle) {
    try {
       ByteArrayOutputStream bout=new ByteArrayOutputStream(); 
       ZipOutputStream zout = new ZipOutputStream(bout);
       ServletOutputStream out =response.getOutputStream();

        for (File file : bundle) {
            FileInputStream fi = new FileInputStream(file);
            byte bytes[] = new byte[(int)file.length()];

          // Read in the bytes
          int offset = 0; 
          int numRead = 0;
          while (offset < bytes.length && (numRead=fi.read(bytes, offset, bytes.length-offset)) >= 0) 
{ offset += numRead; } 

            // Ensure all the bytes have been read in 
          if (offset < bytes.length) { throw new IOException("Could not completely read file "+file.getName()); } 
          fi.close();

          ZipEntry zipEntry = new ZipEntry(file.getName());
          //zipEntry.setCompressedSize(file.length());
          zipEntry.setSize(offset);
          CRC32 crc = new CRC32();
          crc.update(bytes);
          zipEntry.setCrc(crc.getValue());
          zout.putNextEntry(zipEntry);
          zout.write(bytes, 0, offset);
          zout.closeEntry();
          zout.finish(); 
          fi.close();
      }

  zout.close();

  response.setContentType("application/zip");
  response.setHeader("Content-Disposition",
  "attachment; filename=hivseqdb.zip;");
  out.write(bout.toByteArray());
  out.flush();
  out.close();

  } catch (IOException e) {
   // TODO Auto-generated catch block
  e.printStackTrace();
 }
 }
A: 

You need to move the zout.finish(); line outside of the loop.

Donal Boyle