2016-03-30 18 views
0

EDIT: Der Fehler war nicht in diesem Code. Der Download auf dem Frontend war fehlerhaft. Die Zip auf dem Server war in Ordnung, aber das Herunterladen über js hat nicht funktioniert.Schreiben von XML-Dateien in Zip-Datei mit ZipOutputStream - Fehler beim Öffnen

Ich schreibe zwei XML-Dateien in eine Zip-Datei. Ich kann die resultierende Datei nicht öffnen (Fehler: keine Datei und kein Ordner).

Tuple ist eine Klasse, die zwei Strings (A und B) enthält, mein xml-Inhalt. Ich habe das zuerst ohne closeEntry und ohne setSize versucht, das Ergebnis ist das gleiche.

Irgendwelche Ideen? Wie kann ich das debuggen?

private static byte[] createArchive(final Tuple<String, String> body) throws IOException { 

    try (final ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
     final ZipOutputStream zos = new ZipOutputStream(bos)) { 

     final ZipEntry firstEntry = new ZipEntry("first.xml"); 
     firstEntry.setSize(body.getA().getBytes().length); 
     zos.putNextEntry(firstEntry); 
     zos.write(body.getA().getBytes()); 
     zos.closeEntry(); 

     final ZipEntry secondEntry = new ZipEntry("second.xml"); 
     secondEntry.setSize(body.getB().getBytes().length); 
     zos.putNextEntry(secondEntry); 
     zos.write(body.getB().getBytes()); 
     zos.closeEntry(); 

     zos.close(); 

     return bos.toByteArray(); 
    } 
} 
+2

Wo ist der Code zum Schreiben Ihres 'OutputStream' in Datei? – user2004685

+2

Abgesehen von allem anderen rufen Sie 'String.getBytes()' ohne Angabe der Codierung auf. Tun Sie das nicht - * immer * spezifizieren Sie die Kodierung. Sie rufen auch 'getBytes()' mehrmals auf - einmal, um die Länge zu erhalten, und dann wieder, um sie zu schreiben. Ich würde es einmal pro Eintrag aufrufen und das Ergebnis in einem 'byte []' speichern. Vielleicht möchten Sie diese Logik in eine Methode extrahieren, 'writeStringAsZipEntry' oder etwas ähnliches ... –

+0

Das Schreiben wird von Apache Camel gemacht. Dies funktioniert mit anderen Dateien, daher ist es hier nicht enthalten. Der Aufruf getBytes wird immer noch zweimal verwendet, weil ich die Größe nicht zuerst angegeben habe. Ist das überhaupt nötig? –

Antwort

0

Ich glaube, der Fehler ist nicht in dieser Methode. Das folgende Snippet basierend auf Ihrem gebuchten Code erstellt ein gültiges ZIP-Archiv.

try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
     ZipOutputStream zos = new ZipOutputStream(bos)) { 

    byte[] fileA = Files.readAllBytes(Paths.get("/tmp/fileA.xml")); 
    byte[] fileB = Files.readAllBytes(Paths.get("/tmp/fileB.xml")); 
    ZipEntry firstEntry = new ZipEntry("first.xml"); 
    firstEntry.setSize(fileA.length); 
    zos.putNextEntry(firstEntry); 
    zos.write(fileA); 
    zos.closeEntry(); 

    ZipEntry secondEntry = new ZipEntry("second.xml"); 
    secondEntry.setSize(fileB.length); 
    zos.putNextEntry(secondEntry); 
    zos.write(fileB); 
    zos.closeEntry(); 
    zos.close(); 

    Files.write(Paths.get("/tmp/files.zip"), bos.toByteArray()); 
} 

Prüfung des Archiv

jar vtf /tmp/files.zip 
    5 Wed Mar 30 13:15:02 CEST 2016 first.xml 
    5 Wed Mar 30 13:15:02 CEST 2016 second.xml 

Wie Jon Skeet erwähnte es höchstwahrscheinlich zu body.getA() verwendet. Wenn diese Methode String zurückgibt, sollten Sie die Codierung angeben, um sicherzustellen, dass der Dateiinhalt nicht verstümmelt ist.