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}