Compressing / Decompressing Folders & Files

Viewed 5197

Does anyone know of a good way to compress or decompress files and folders in C# quickly? Handling large files might be necessary.

9 Answers

The .Net 2.0 framework namespace System.IO.Compression supports GZip and Deflate algorithms. Here are two methods that compress and decompress a byte stream which you can get from your file object. You can substitute GZipStream for DefaultStream in the methods below to use that algorithm. This still leaves the problem of handling files compressed with different algorithms though.

public static byte[] Compress(byte[] data)
{
    MemoryStream output = new MemoryStream();

    GZipStream gzip = new GZipStream(output, CompressionMode.Compress, true);
    gzip.Write(data, 0, data.Length);
    gzip.Close();

    return output.ToArray();
}

public static byte[] Decompress(byte[] data)
{
    MemoryStream input = new MemoryStream();
    input.Write(data, 0, data.Length);
    input.Position = 0;

    GZipStream gzip = new GZipStream(input, CompressionMode.Decompress, true);

    MemoryStream output = new MemoryStream();

    byte[] buff = new byte[64];
    int read = -1;

    read = gzip.Read(buff, 0, buff.Length);

    while (read > 0)
    {
        output.Write(buff, 0, read);
        read = gzip.Read(buff, 0, buff.Length);
    }

    gzip.Close();

    return output.ToArray();
}

My answer would be close your eyes and opt for DotNetZip. It's been tested by a large community.

This is very easy to do in java, and as stated above you can reach into the java.util.zip libraries from C#. For references see:

java.util.zip javadocs
sample code

I used this a while ago to do a deep (recursive) zip of a folder structure, but I don't think I ever used the unzipping. If I'm so motivated I may pull that code out and edit it into here later.

You can create zip file with this method:

public async Task<string> CreateZipFile(string sourceDirectoryPath, string name)
{
    var path = HostingEnvironment.MapPath(TempPath) + name;
    await Task.Run(() =>
    {
        if (File.Exists(path)) File.Delete(path);
        ZipFile.CreateFromDirectory(sourceDirectoryPath, path);
    });
    return path;
}

and then you can unzip zip file with this methods:

1- This method work with zip file path

public async Task ExtractZipFile(string filePath, string destinationDirectoryName)
{
    await Task.Run(() =>
    {
        var archive = ZipFile.Open(filePath, ZipArchiveMode.Read);
        foreach (var entry in archive.Entries)
        {
            entry.ExtractToFile(Path.Combine(destinationDirectoryName, entry.FullName), true);
        }
        archive.Dispose();
    });
}

2- This method work with zip file stream

public async Task ExtractZipFile(Stream zipFile, string destinationDirectoryName)
{
    string filePath = HostingEnvironment.MapPath(TempPath) + Utility.GetRandomNumber(1, int.MaxValue);
    using (FileStream output = new FileStream(filePath, FileMode.Create))
    {
        await zipFile.CopyToAsync(output);
    }
    await Task.Run(() => ZipFile.ExtractToDirectory(filePath, destinationDirectoryName));
    await Task.Run(() => File.Delete(filePath));
}
Related