Make a ZIP archive flat

Your zip archive may have other zip archives inside it. One may want to extract the nested zip archive’s contents into the parent archive to get a flat structure.

Current archive structure
outer.zip
 ├first.txt
 ├inner.zip
 │ ├game.exe
 │ └subitem.bin
 └picture.gif
Desired archive structure
flatten.zip
 ├first.txt
 ├picture.gif
 ├game.exe
 └subitem.bin

If you are not familiar with Aspose.Zip read how to extract zip archive first.

Overal explanation

First, we need to list all the entries of the archive. Regular entries should be kept as they are, we should not even decompress them. Entries that are archives themselves need to be extracted to memory and removed from the outer archive. Their content needs to be included in the main archive.

Detecting entries that are archives

Lets decide which entries are archives itself. We can figure this out by extension of entry name. Later we will remove those entries from main archive, so keep such entries in a list.

1if (entry.Name.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) {
2    entriesToDelete.Add(entry);
3    ...
4}

Extracting entry’s content to memory

Aspose.Zip allows extracting the content of zip entry into any writable stream, not only to a file. So, we can extract a nested archive to a memory stream.

Please note: the virtual memory must be big enough to keep all extracted content.

1MemoryStream innerCompressed = new MemoryStream();
2entry.Open().CopyTo(innerCompressed); 

After that innerCompressed stream contains the inner archive itself. The Archive constructor allows decompressing the stream provided. So, we can extract it as well:

1Archive inner = new Archive(innerCompressed);

Excluding entries

We can remove an entry from zip archive with particular method.

1foreach (ArchiveEntry e in entriesToDelete) { outer.DeleteEntry(e); }

Put it all together

Here is the complete algorithm.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.