Cr�er une archive ZIP � plat
Votre archive zip peut contenir d�autres archives zip. On souhaitera peut-�tre extraire le contenu de l�archive zip imbriqu�e dans l�archive parent pour obtenir une structure plate.
Structure actuelle des archives
outer.zip +first.txt +inner.zip � +game.exe � +subitem.bin +picture.gif
Structure d'archive 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 l’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, il ne faut 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�cidons quelles entr�es sont elles-m�mes des archives. Nous pouvons comprendre cela par extension du nom de l�entr�e. Plus tard, nous supprimerons ces entr�es de l’archive principale, conservez donc ces entr�es dans une liste.
1if (entry.Name.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) {
2 entriesToDelete.Add(entry);
3 ...
4}Extraction du contenu de l’entr�e en m�moire
Aspose.Zip permet d’extraire le contenu d’une entr�e zip dans n’importe quel flux inscriptible, pas seulement dans un fichier. Ainsi, nous pouvons extraire une archive imbriqu�e dans un flux m�moire.
Attention : la m�moire virtuelle doit �tre suffisamment grande pour conserver tout le contenu extrait.
1MemoryStream innerCompressed = new MemoryStream();
2entry.Open().CopyTo(innerCompressed); Apr�s ce flux innerCompressed contient l�archive interne elle-m�me. Le Constructeur d’archive permet de d�compresser le flux fourni. Nous pouvons donc l’extraire �galement�:
1Archive inner = new Archive(innerCompressed);Hors entr�es
Nous pouvons supprimer une entr�e de l’archive zip avec m�thode particuli�re.
1foreach (ArchiveEntry e in entriesToDelete) { outer.DeleteEntry(e); }Mettez tout cela ensemble
Voici l’algorithme complet.
1 using (Archive outer = new Archive("outer.zip"))
2 {
3 List<ArchiveEntry> entriesToDelete = new List<ArchiveEntry>();
4 List<string> namesToInsert = new List<string>();
5 List<MemoryStream> contentToInsert = new List<MemoryStream>();
6
7 foreach (ArchiveEntry entry in outer.Entries)
8 {
9 if (entry.Name.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) // Find an entry which is an archive itself
10 {
11 entriesToDelete.Add(entry); // Keep reference to the entry in order to remove it from the archive later
12 MemoryStream innerCompressed = new MemoryStream();
13 entry.Open().CopyTo(innerCompressed); //This extracts the entry to a memory stream
14
15 using (Archive inner = new Archive(innerCompressed)) // We know that content of the entry is an zip archive so we may extract
16 {
17 foreach (ArchiveEntry ie in inner.Entries) // Loop over entries of inner archive
18 {
19 namesToInsert.Add(ie.Name); // Keep the name of inner entry.
20 MemoryStream content = new MemoryStream();
21 ie.Open().CopyTo(content);
22 contentToInsert.Add(content); // Keep the content of inner entry.
23 }
24 }
25 }
26 }
27
28 foreach (ArchiveEntry e in entriesToDelete)
29 outer.DeleteEntry(e); // Delete all the entries which are archives itself
30
31 for (int i = 0; i < namesToInsert.Count; i++)
32 outer.CreateEntry(namesToInsert[i], contentToInsert[i]); // Adds entries which were entries of inner archives
33
34 outer.Save("flatten.zip");
35 }