Beim Versuch, ein Archiv unter Verwendung der java.util.zip
zu zippen, stieß ich auf viele Probleme, von denen ich die meisten löste. Jetzt, wo ich endlich einen Output bekomme, habe ich Probleme mit der "richtigen" Ausgabe. Ich habe eine extrahierte ODT-Datei (Verzeichnis wäre passender eine Beschreibung), an der ich einige Änderungen vorgenommen habe. Jetzt möchte ich dieses Verzeichnis komprimieren, um die ODT-Dateistruktur neu zu erstellen. Das Zippen des Verzeichnisses und das Umbenennen mit .odt funktioniert einwandfrei, es sollte also kein Problem geben.java.util.zip - Verzeichnisstruktur neu erstellen
Das Hauptproblem ist, dass ich die interne Struktur des Verzeichnisses verliere. Alles wird "flach" und ich finde keinen Weg, die ursprüngliche vielschichtige Struktur zu erhalten. Ich würde mich über einige Hilfe freuen, da ich das Problem nicht zu finden scheint.
Hier sind die entsprechenden Code-Schnipsel:
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
FILEPATH.substring(0, FILEPATH.lastIndexOf(SEPARATOR) + 1).concat("test.zip")));
compressDirectory(TEMPARCH, out);
Die SEPARATOR
ist die Systemdatei Separator und die FILEPATH
ist die Filepath des ursprünglichen ODT, die ich überschreiben, aber noch nicht hier zu Testzwecken durchgeführt. Ich schreibe einfach in eine test.zip Datei im selben Verzeichnis.
private void compressDirectory(String directory, ZipOutputStream out) throws IOException
{
File fileToCompress = new File(directory);
// list contents.
String[] contents = fileToCompress.list();
// iterate through directory and compress files.
for(int i = 0; i < contents.length; i++)
{
File f = new File(directory, contents[i]);
// testing type. directories and files have to be treated separately.
if(f.isDirectory())
{
// add empty directory
out.putNextEntry(new ZipEntry(f.getName() + SEPARATOR));
// initiate recursive call
compressDirectory(f.getPath(), out);
// continue the iteration
continue;
}else{
// prepare stream to read file.
FileInputStream in = new FileInputStream(f);
// create ZipEntry and add to outputting stream.
out.putNextEntry(new ZipEntry(f.getName()));
// write the data.
int len;
while((len = in.read(data)) > 0)
{
out.write(data, 0, len);
}
out.flush();
out.closeEntry();
in.close();
}
}
}
Das Verzeichnis, das die Dateien enthält, ist irgendwo im Benutzerraum zip und nicht im selben Verzeichnis wie die resultierenden Datei. Ich nehme an, das könnte Ärger sein, aber ich kann nicht wirklich sehen, wie. Ich dachte auch, dass das Problem darin bestehen könnte, den gleichen Stream für die Ausgabe zu verwenden, aber ich kann nicht sehen, wie. Ich sah in einigen Beispielen und Tutorials, dass sie getPath()
anstelle von getName()
verwenden, aber das Ändern gibt mir eine leere Zip-Datei.
Vielen Dank! Leider kann ich nicht sehen, wie das ursprüngliche Verzeichnisformat mit Ihrem Komprimierungscode beibehalten wird. Im ODT verwende ich leere Verzeichnisse. Soweit ich Ihren Code verstehe, werden diese Verzeichnisse niemals erstellt. Vermisse ich vielleicht etwas? – Eric
Verzeichnisse sind leere Einträge mit einem Namen, der mit '/' endet. Ich habe den Code geändert. – McDowell
Ich habe die Struktur Ihres Codes angepasst und die rekursiven Aufrufe aufgegeben. Ich denke, es war der falsche Weg, dies zu betrachten. Der Code läuft reibungslos mit einer Ausnahme; Es fügt den meisten untergeordneten Verzeichnissen leere Ordner hinzu, auch wenn sie nicht leer sind. Ich habe festgestellt, dass das Entfernen der folgenden Zeile das Problem löst: name = name.endsWith ("/")? Name: Name + "/"; Ich vermute, dass beim Hinzufügen eines Verzeichnisses durch Anhängen des "\" auch ein leerer Ordner darin erstellt wird. Indem man einfach die ZipEntries auf den Aufbau der Struktur achtet, scheint alles in Ordnung zu sein. Danke Ihnen allen für Ihre Hilfe! – Eric