Unzip a memorystream (Contains the zip file) and get the files

Yes, .Net 4.5 now supports more Zip functionality.

Here is a code example based on your description.

In your project, right click on the References folder and add a reference to System.IO.Compression

using System.IO.Compression;

Stream data = new MemoryStream(); // The original data
Stream unzippedEntryStream; // Unzipped data from a file in the archive

ZipArchive archive = new ZipArchive(data);
foreach (ZipArchiveEntry entry in archive.Entries)
{
    if(entry.FullName.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
    {
         unzippedEntryStream = entry.Open(); // .Open will return a stream
         // Process entry data here
    }
}

Hope this helps.


We use DotNetZip, and I can unzip the contents of a zip file from a Stream into memory. Here's the sample code for extracting a specifically named file from a stream (LocalCatalogZip) and returning a stream to read that file, but it'd be easy to expand on it.

private static MemoryStream UnZipCatalog()
{
    MemoryStream data = new MemoryStream();
    using (ZipFile zip = ZipFile.Read(LocalCatalogZip))
    {
        zip["ListingExport.txt"].Extract(data);
    }
    data.Seek(0, SeekOrigin.Begin);
    return data;
}

It's not the library you're using now, but if you can change, you can get that functionality.


Here's a variation which would return a Dictionary<string,MemoryStream> of for the contents of every file of a zip file.

private static Dictionary<string,MemoryStream> UnZipToMemory()
{
    var result = new Dictionary<string,MemoryStream>();
    using (ZipFile zip = ZipFile.Read(LocalCatalogZip))
    {
        foreach (ZipEntry e in zip)
        {
            MemoryStream data = new MemoryStream();
            e.Extract(data);
            result.Add(e.FileName, data);
        }
    }

    return result;
}

I've just had a similar issue and the answer I found which I think seems to be fairly elegant is to use #ZipLib (available using nuget) and do the following:

private byte[] GetUncompressedPayload(byte[] data)
{
    using (var outputStream = new MemoryStream())
    using (var inputStream = new MemoryStream(data))
    {
        using (var zipInputStream = new ZipInputStream(inputStream))
        {
            zipInputStream.GetNextEntry();
            zipInputStream.CopyTo(outputStream);
        }
        return outputStream.ToArray();
    }
}

This seems to have worked a treat. Hope this helps.

Tags:

C#