So erstellen Sie ein flaches ZIP-Archiv

Ihr Zip-Archiv kann andere Zip-Archive enthalten. Vielleicht m�chten Sie den Inhalt des verschachtelten Zip-Archivs in das �bergeordnete Archiv extrahieren, um eine flache Struktur zu erhalten.

Aktuelle Archivstruktur
outer.zip
 +first.txt
 +inner.zip
 � +game.exe
 � +subitem.bin
 +picture.gif
Gew�nschte Archivstruktur
flatten.zip
 +first.txt
 +picture.gif
 +game.exe
 +subitem.bin

Wenn Sie mit Aspose.Zip nicht vertraut sind, lesen Sie zuerst, wie man Zip-Archiv extrahiert.

Einfache Erkl�rung

Zuerst m�ssen wir alle Eintr�ge des Archivs auflisten. Regul�re Eintr�ge sollten so belassen werden, wie sie sind, wir sollten sie nicht einmal dekomprimieren. Eintr�ge, die selbst Archive sind, m�ssen in den Speicher extrahiert und aus dem �u�eren Archiv entfernt werden. Ihr Inhalt muss in das Hauptarchiv aufgenommen werden.

Erkennen von Eintr�gen, die Archive sind

Lassen Sie uns entscheiden, welche Eintr�ge selbst Archive sind. Wir k�nnen dies anhand der Erweiterung des Eintragsnamens herausfinden. Sp�ter werden wir diese Eintr�ge aus dem Hauptarchiv entfernen, also behalten wir solche Eintr�ge in einer Liste.

1if(eintrag.getName().toLowerCase(Locale.ROOT).endsWith(".zip")) {
2    entriesToDelete.add(Eintrag);
3    ...
4}

Inhalt des Eintrags in den Speicher extrahieren

Aspose.Zip erm�glicht das Extrahieren des Inhalts eines Zip-Eintrags in einen beliebigen beschreibbaren Stream, nicht nur in eine Datei. Wir k�nnen also ein verschachteltes Archiv in einen Speicherstrom extrahieren.

Bitte beachten Sie: Der virtuelle Speicher muss gro� genug sein, um alle extrahierten Inhalte zu speichern.

1byte[] b = new byte[8192];
2int bytesLesen;
3InputStream entryStream = entry.open();
4ByteArrayOutputStream innerCompressed = new ByteArrayOutputStream();
5while (0 < (bytesRead = entryStream.read(b, 0, b.length))) {
6    innerCompressed.write(b, 0, bytesRead);
7}

Danach enth�lt innerCompressed stream das innere Archiv selbst. Der Archive constructor erm�glicht die Dekomprimierung des bereitgestellten Streams. Wir k�nnen ihn also auch extrahieren:

1Archive inner = new Archive(new ByteArrayInputStream(innerCompressed.toByteArray()));

Eintr�ge ausschlie�en

Mit bestimmte Methode k�nnen wir einen Eintrag aus dem Zip-Archiv entfernen.

1for(ArchiveEntry e : entriesToDelete) {
2    outer.deleteEntry(e);
3}

Alles zusammenf�gen

Hier ist der vollst�ndige Algorithmus.

 1try(Archiv outer = new Archiv("outer.zip")) {
 2    ArrayList<ArchiveEntry> entriesToDelete = new ArrayList<ArchiveEntry>();
 3    ArrayList<String> namesToInsert = new ArrayList<String>();
 4    ArrayList<InputStream> contentToInsert = new ArrayList<InputStream>();
 5    for(ArchiveEntry entry : outer.getEntries()) {
 6        // Einen Eintrag finden, der selbst ein Archiv ist
 7        if(entry.getName().toLowerCase(Locale.ROOT).endsWith(".zip")) {
 8            // Behalte den Verweis auf den Eintrag, um ihn sp�ter aus dem Archiv entfernen zu k�nnen
 9            entriesToDelete.add(Eintrag);
10
11            //This extracts the entry to a memory stream
12            byte[] b = new byte[8192];
13            int bytesRead;
14            InputStream entryStream = entry.open();
15            ByteArrayOutputStream innerCompressed = new ByteArrayOutputStream();
16            while (0 < (bytesRead = entryStream.read(b, 0, b.length))) {
17                innerCompressed.write(b, 0, bytesRead);
18            }
19
20            // We know that content of the entry is a zip archive, so we may extract
21            try(Archive inner = new Archive(new ByteArrayInputStream(innerCompressed.toByteArray()))) {
22
23                // Loop over entries of inner archive
24                for(ArchiveEntry ie : inner.getEntries()) {
25
26                    // Keep the name of inner entry.
27                    namesToInsert.add(ie.getName());
28
29                    InputStream ieStream = ie.open();
30                    ByteArrayOutputStream content = new ByteArrayOutputStream();
31                    while (0 < (bytesRead = ieStream.read(b, 0, b.length))) {
32                        content.write(b, 0, bytesRead);
33                    }
34
35                    // Keep the content of inner entry.
36                    contentToInsert.add(new ByteArrayInputStream(content.toByteArray()));
37                }
38            }
39        }
40    }
41
42    for(ArchiveEntry e : entriesToDelete) {
43        // Delete all the entries which are archives itself
44        outer.deleteEntry(e);
45    }
46
47    for(int i = 0; i < namesToInsert.size(); i++) {
48        // Adds entries which were entries of inner archives
49        outer.createEntry(namesToInsert.get(i), contentToInsert.get(i));
50    }
51
52    outer.save("flatten.zip");
53} catch (Exception ex) {
54    System.out.println(ex);
55}
Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.