2011-01-13 2 views
5

Mein Ziel ist es, mehrere java.io.File Objekte in eine Zip-Datei und drucken auf HttpServletResponse für den Benutzer zum Download.So erstellen Sie ZIP-Datei für eine Liste von "virtuellen Dateien" und Ausgabe auf httpservetrisponse

Die Dateien wurden vom JAXB Marshaller erstellt. Es ist ein java.io.File Objekt, aber es ist nicht wirklich auf dem Dateisystem (es ist nur im Speicher), also kann ich keinen FileInputStream erstellen.

Alle Ressourcen, die ich gesehen habe, verwenden den OutputStream, um ZIP-Dateiinhalte zu drucken. Aber alle diese Ressourcen verwenden FileInputStream (die ich nicht verwenden kann).

Wer weiß, wie ich das erreichen kann?

+3

Was meinen Sie es ein 'java.io.File' ist? Ein 'File'-Objekt ist nur ein schickes Adressobjekt; Es enthält keinen Dateiinhalt. Wo sind deine Daten? – erickson

Antwort

3

Stellt sich heraus, ich bin ein Idiot :) Die Datei, die "geschaffen" wurde war Speichern auf ungültigen Pfad und Verschlucken der Ausnahme, also dachte ich, dass es "erstellt" wurde, ok. Als ich versuchte, einen neuen FileInputStream zu instanziieren, beklagte es sich jedoch, dass die Datei nicht existierte (zu Recht). Ich hatte einen Brainfart und nahm an, dass das java.io.File-Objekt tatsächlich irgendwo Dateiinformationen enthielt. Aber wie Erickson darauf hingewiesen hat, war das falsch.

Danke Ralph für den Code, ich habe es verwendet, nachdem ich das ungültige Pathing-Problem gelöst habe.

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

Invalid Pathing-Problem? - was meinst du - gibt es einen serios Bug im Code meiner Antwort? – Ralph

+0

Nein, Ihr Code war perfekt. Das war mein Fehler. – Corey

6

Werfen Sie einen Blick auf die Apache Commons Compress Bibliothek, es stellte die Funktion zur Verfügung, die Sie benötigen.

Natürlich "Erickson" ist Recht mit seinem Kommentar zu Ihrer Frage. Sie benötigen die Datei conentet und nicht das Objekt java.io.File. In meinem Beispiel gehe ich davon aus, dass Sie eine Methode byte[] getTheContentFormSomewhere(int fileNummer) haben, die den Dateiinhalt (im Speicher) für die Dateinummer-Datei zurückgibt. - Natürlich ist diese Funktion schlechtes Design, aber es ist nur für die Illustration.

Es sollte ein bisschen wie diese Arbeit:

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 Ihrer 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(); 
Verwandte Themen