压缩/解压文件夹和文件

60

有人知道如何在C#中快速压缩或解压文件和文件夹的好方法吗?需要处理大文件。

9个回答

27

.Net 2.0框架命名空间System.IO.Compression支持GZip和Deflate算法。以下是两种压缩和解压缩字节流的方法,你可以从文件对象中获取字节流。你可以在下面的方法中用GZipStream替换DefaultStream以使用该算法。但这仍然存在处理不同算法压缩的文件的问题。

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();
}

22

注意:几年前我在SharpZip代码中发现了一个int溢出错误,导致它在偶然具有正确值组合的随机文件上失败。不确定是否已经修复,但是从记忆中,我在SharpZip源代码中将一个int变量更改为long以避免溢出。我将不得不尝试找到我旧的修复后的SharpZip代码,并检查它是否与最新版本匹配。 - iCollect.it Ltd

10

10
你可以使用像Tom指出的SharpZip这样的第三方库
另一种方法(不需要使用第三方库)是使用Windows Shell API。您需要在C#项目中设置对Microsoft Shell Controls和Automation COM库的引用。Gerald Gibson在以下网址提供了一个示例: 互联网档案馆存档的副本

8

我的回答是闭上眼睛选择DotNetZip。它已经被广大社区测试过。


6

5
这在Java中非常容易实现,正如上面所述,您可以从C#访问java.util.zip库。有关参考,请参见: java.util.zip javadocs
示例代码 我以前用过它来对文件夹结构进行深度(递归)压缩,但我不认为我曾经使用过解压缩功能。如果我有兴趣,我可能会将该代码提取出来并编辑到这里。

5

0

你可以使用这个方法创建zip文件:

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;
}

然后您可以使用以下方法解压缩zip文件:

1- 此方法适用于zip文件路径

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- 这个方法适用于 zip 文件流

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));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接