2011-01-13 18 views
5

Il mio obiettivo è mettere più oggetti java.io.File in un file zip e stampare su HttpServletResponse affinché l'utente possa scaricare.Come creare un file ZIP per un elenco di "file virtuali" e inviarlo a httpservletresponse

I file sono stati creati dal marshaller JAXB. È un oggetto java.io.File, ma non è in realtà sul file system (è solo in memoria), quindi non posso creare un FileInputStream.

Tutte le risorse che ho visto utilizzano OutputStream per stampare il contenuto del file zip. Ma tutte queste risorse usano FileInputStream (che non posso usare).

Qualcuno sa come posso realizzare questo?

+3

Cosa vuoi dire che sia un 'java.io.File'? Un oggetto 'File' è solo un oggetto di indirizzo di fantasia; non porta alcun contenuto di file. Dove sono i tuoi dati? – erickson

risposta

3

venuto fuori che sono un idiota :) Il file che si stava "creato" era salvare su percorso non valido e ingoiare l'eccezione, quindi ho pensato che fosse "creato" ok. Quando ho provato a creare un'istanza di un nuovo FileInputStream, tuttavia, si lamentava che il file non esisteva (giustamente). Avevo un brainfart e pensavo che l'oggetto java.io.File contenesse effettivamente informazioni di file in esso da qualche parte. Ma come ha sottolineato Erickson, era falso.

Grazie Ralph per il codice, l'ho utilizzato dopo aver risolto il problema del percorso non valido.

Il mio codice:

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 di invalidità del percorso? - cosa intendi - c'è un bug serios nel codice della mia risposta? – Ralph

+0

Nessun codice era perfetto. È stata colpa mia – Corey

6

Dai un'occhiata alla libreria Apache Commons Compress, ha dimostrato la funzionalità di cui hai bisogno.

Naturalmente "erickson" ha ragione con il suo impegno per la tua domanda. Avrai bisogno del file conentet e non dell'oggetto java.io.File. Nel mio esempio presumo che tu abbia un metodo byte[] getTheContentFormSomewhere(int fileNummer) che restituisce il contenuto del file (in memoria) per il fileNummer-esimo file. - Ovviamente questa funzione è di design scadente, ma è solo per ilustration.

Dovrebbe funzionare un po 'come questo:

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 del vostro controller 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(); 
Problemi correlati