Search code examples
c#.netsharpziplib

How to read data from inner archives without extracting zip file?


I have a zip file which contains inner zip file (Ex:ZipFile1.zip->ZipFile2.zip->file.txt). I want to read the data of inner archive file content (file.txt) using ICSharpCode.SharpZipLib library without extracting to disk. Is it possible? If it is possible, Let me know how to get this.


Solution

  • Based on this answer, you can open a file within the zip as a Stream. You can also open a ZipFile from a Stream. I'm sure you can see where this is heading.

    using (var zip = new ZipFile("ZipFile1.zip"))
    {
        var nestedZipEntry = zip.GetEntry("ZipFile2.zip");
        using (var nestedZipStream = zip.GetInputStream(nestedZipEntry))
        using (var nestedZip = new ZipFile(nestedZipStream))
        {
            var fileEntry = nestedZip.GetEntry("file.txt");
            using (var fileStream = nestedZip.GetInputStream(fileEntry))
            using (var reader = new StreamReader(fileStream))
            {
                Console.WriteLine(reader.ReadToEnd());
            }
        }
    }
    

    What we're doing here:

    1. Open ZipFile1.zip
    2. Find the entry for ZipFile2.zip
    3. Open ZipFile2.zip as a Stream
    4. Create a new ZipFile object around nestedZipStream.
    5. Find the entry for file.txt
    6. Create a StreamReader around fileStream to read the text file.
    7. Read the contents of file.txt and output it to the console.

    Try it online - in this sample, the base64 data is the binary data of a zip file which contains "test.zip", which in turn contains "file.txt". The contents of that text file is "hello".

    P.S. If an entry isn't found then GetEntry will return null. You'll want to check for that in any code you write. It works here because I'm sure that these entries exist in their respective archives.