Comment cr�er une archive ZIP plate

Votre archive zip peut contenir d’autres archives zip. On peut vouloir extraire le contenu de l’archive zip imbriqu�e dans l’archive m�re pour obtenir une structure plate.

Structure actuelle de l'archive
outer.zip
 +first.txt
 +inner.zip
 � +game.exe
 � +subitem.bin
 +picture.gif
Structure des archives souhait�e
flatten.zip
 +first.txt
 +picture.gif
 +game.exe
 +subitem.bin

Si vous n’�tes pas familier avec Aspose.Zip, lisez d’abord comment extraire une archive zip.

Explication g�n�rale

Tout d’abord, nous devons lister toutes les entr�es de l’archive. Les entr�es r�guli�res doivent �tre conserv�es telles quelles, nous ne devons m�me pas les d�compresser. Les entr�es qui sont elles-m�mes des archives doivent �tre extraites de la m�moire et supprim�es de l’archive externe. Leur contenu doit �tre inclus dans l’archive principale.

D�tection des entr�es qui sont des archives

D�terminons quelles entr�es sont des archives. Nous pouvons le d�couvrir par l’extension du nom de l’entr�e. Plus tard, nous supprimerons ces entr�es de l’archive principale, donc gardons ces entr�es dans une liste.

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

Extraction du contenu de l’entr�e dans la m�moire

Aspose.Zip permet d’extraire le contenu d’une entr�e zip dans n’importe quel flux accessible en �criture, et pas seulement dans un fichier. Ainsi, nous pouvons extraire une archive imbriqu�e dans un flux m�moire.

Remarque : la m�moire virtuelle doit �tre suffisamment grande pour contenir tout le contenu extrait.

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

Ensuite, le flux innerCompressed contient l’archive interne elle-m�me. Le Constructeur d’archive permet de d�compresser le flux fourni. Nous pouvons donc �galement l’extraire :

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

Exclusion des entr�es

Nous pouvons supprimer une entr�e de l’archive zip avec m�thode particuli�re.

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

Mettre le tout ensemble

Voici l’algorithme complet.

 1try(Archive outer = new Archive("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        // Recherche d'une entr�e qui est elle-m�me une archive
 7        if(entry.getName().toLowerCase(Locale.ROOT).endsWith(".zip")) {
 8            // Conserver la r�f�rence � l'entr�e afin de la supprimer de l'archive ult�rieurement
 9            entriesToDelete.add(entry) ;
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.