2011-01-13 15 views
5

Mi objetivo es poner múltiples objetos java.io.File en un archivo zip e imprimirlos en HttpServletResponse para que el usuario los descargue.Cómo crear un archivo ZIP para una lista de "archivos virtuales" y salida a httpservletresponse

Los archivos fueron creados por JAXB Marshaller. Es un objeto java.io.File, pero en realidad no está en el sistema de archivos (solo está en la memoria), así que no puedo crear un FileInputStream.

Todos los recursos que he visto usan OutputStream para imprimir el contenido del archivo zip. Pero, todos esos recursos usan FileInputStream (que no puedo usar).

¿Alguien sabe cómo puedo lograr esto?

+3

¿Qué quiere decir que es un 'java.io.File'? Un objeto 'File' es solo un objeto de dirección elegante; no tiene ningún contenido de archivo. ¿Dónde están tus datos? – erickson

Respuesta

3

resulta que soy un idiota :) El archivo que se estaba "creado" era guardando en una ruta inválida y tragándose la excepción, así que pensé que se estaba "creando" bien. Cuando intenté crear una instancia de un nuevo FileInputStream, sin embargo, se quejó de que el archivo no existía (con razón). Tuve un brainfart y asumí que el objeto java.io.File en realidad contenía información de archivos en algún lugar. Pero como Erickson señaló, eso fue falso.

Gracias Ralph por el código, lo usé después de resolver el problema de la ruta no válida.

Mi código:

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(); 
+0

¿Problema de ruta invalidada? - ¿Qué quieres decir? ¿Hay algún error serios en el código de mi respuesta? – Ralph

+0

No, su código era perfecto. Fue mi culpa. – Corey

6

Eche un vistazo a la librería Apache Commons Compress, le proporcionó la funcionalidad que necesita.

Por supuesto "erickson" está en lo cierto con su comentario a su pregunta. Necesitará el archivo conentet y no el objeto java.io.File. En mi ejemplo, supongo que tiene un método byte[] getTheContentFormSomewhere(int fileNummer) que devuelve el contenido del archivo (en memoria) para el archivoNummer-th. - Por supuesto, esta función es un diseño pobre, pero solo es para la ilustración.

Se debe trabajar un poco como esto:

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 de su controlador http:

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(); 
Cuestiones relacionadas