Question

I know there are libraries out there for working with ZIP files. And, you can alternatively use the functionality built into Windows for working ZIP files.

But, I'm wondering if anyone has worked out how to use the tools built into the System.IO.Compression namespace within .NET for reading/writing ZIP files? Or, is it not possible using only this namespace?

UPDATED: I've seem someone comment that the System.IO.Packaging namespace might be usefull with this also. Does anyone know exactly how to do it?

Was it helpful?

Solution

MSDN has a complete example http://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage.aspx using the ZipPackage class. Requires .NET 3.5.

OTHER TIPS

Dave, very nice!! I didn't know that was in there.

Now that I know what to look for, I was able to find an article with a small code sample on how to use it: http://weblogs.asp.net/jgalloway/archive/2007/10/25/creating-zip-archives-in-net-without-an-external-library-like-sharpziplib.aspx

On a related note, I also found the DotNetZip project that looks extremely easy to use.

You will want to use a third-party library, like http://www.codeplex.com/DotNetZip, rather than trying to use GZipStream or DeflateStream to read a zip file.

The ***Stream classes in .NET can let you read or write compressed streams of bytes. These classes DO NOT read or write zip files. The zip file is compressed data surrounded by "an envelope" or a header. Think of it as metadata - it includes the name of the file, timestamp, CRC, and a bunch of other stuff. The **Stream classes produce only the stream of compressed data, and do not know how to produce or consume the metadata, which is described in the PKZip format specification maintained by PKWare.

Third party libraries like DotNetZip handle the metadata in a ZIP archive. They may or may not use the System.IO.Compression.DeflateStream() class to produced the compressed stream of bytes. In previous releases, for example, DotNetZip used the built-in DeflateStream. As of v1.7, DotNetZip includes its own DeflateStream which is more efficient than the one shipped in the .NET Framework. As an added benefit, the embedded DeflateStream in DotNetZip allows DotNetZip to be used on the .NET Compact Framework 2.0, which lacks a System.IO.Compression.DeflateStream. (it was added in Compact Framework 3.5)

There's a good forum on the DotNetZip site if you have more questions. Example C# code:

    try
    {
        using (ZipFile zip = new ZipFile())
        {
            zip.AddDirectory(DirectoryToZip); // recurses subdirs
            zip.Save(Filename);
        }
    }
    catch (System.Exception ex1)
    {
        System.Console.Error.WriteLine("exception: " + ex1);
    }

Since .NET 4.5, Microsoft has offered the ZipArchive class to the System.IO.Compression namespace. Unlike other classes in that namespace, though, like GZipStream and Deflate stream, the ZipArchive requires a reference to the System.IO.Compression.dll assembly.

It's fairly simple to use, and the link above to MSDN provides some good examples.

Additionally, Microsoft has created the Microsoft Compression NuGet package, which adds support for ZipArchive and related classes to Windows Phone 8 and other Portable Class Libraries

An older thread, I know, but I'd like to point out that .NET 4.5 added extensive improvements to system.io.compression. It can now manipulate .zip files quite well, even down to exposing individual files within the zip as streams capable or read and write without the step of extracting and compressing the files.

Yes, I've used it in the past. I sub-classed DataSet once to support persisting itself out to a file (via the ReadXML/WriteXML method). As an added bonus, I decided to allow it to be, optionally, compressed if desired (this, as you all should already know, is extremely effective with textual data like XML).

I used the GZipStream class (it was my understanding at the time that the related DeflateStream was merely GZip without header information, or some such — I'm sure someone could correct me on this). It works quite simply by piggy-backing on top of another stream and thus you then use the GZipStream in its place. In my case, it was piggy-backing on a FileStream.

Given a MemoryStream to be filled with the output of myDataSet.WriteXML(), I did something like the following:

if (CompressData)
{
    // Write to memory
    mStream = new MemoryStream();
    Save(mStream);
    mStream.Seek(0, SeekOrigin.Begin);

    // Filter that through a GZipStream and then to file
    fStream = new FileStream(Path.Combine(CacheFilePath, FileName + ".gz"),
                             FileMode.OpenOrCreate);
    zipStream = new GZipStream(fStream, CompressionMode.Compress, true);

    Pump(mStream, zipStream);
}
else
{
    // Write straight to file
    fStream = new FileStream(Path.Combine(CacheFilePath, FileName),
                             FileMode.OpenOrCreate);
    Save(fStream);
}

Where Save() and Pump() are simple methods like the following:

private void Pump(Stream input, Stream output)
{
    int n;
    byte[] bytes = new byte[4096]; // 4KiB at a time

    while ((n = input.Read(bytes, 0, bytes.Length)) != 0)
    {
        output.Write(bytes, 0, n);
    }
}

public void Save(Stream stream)
{
    AcceptChanges();

    WriteXml(stream, XmlWriteMode.WriteSchema);
}
    public static void zIpDatabseFile(string srcPath, string destPath)
    {//This is for  Zip a File
        using (var source = new FileStream(srcPath, FileMode.Open, FileAccess.Read, FileShare.Read))
        using (var dest = new FileStream(destPath, FileMode.OpenOrCreate, FileAccess.Write))
        using (var zip = new GZipStream(dest, CompressionMode.Compress))
        {
            source.CopyTo(zip);
        }
    }
    public static void uNzIpDatabaseFile(string SrcPath, string DestPath)
    {// This is for unzip a files.
        using (var source = new FileStream(SrcPath, FileMode.Open, FileAccess.Read, FileShare.Read))
        using (var dest = new FileStream(DestPath, FileMode.OpenOrCreate, FileAccess.Write))
        using (var zip = new GZipStream(source, CompressionMode.Decompress))
        {
            zip.CopyTo(dest);
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top