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}