如何使用System.IO.Compression读写ZIP文件?

问题描述 投票:0回答:9

我知道有可用于处理 ZIP 文件的库。而且,您也可以使用 Windows 内置的功能来处理 ZIP 文件

但是,我想知道是否有人已经弄清楚如何使用 .NET 中的 System.IO.Compression 命名空间中内置的工具来读取/写入 ZIP 文件?或者,仅使用这个命名空间是不可能的吗?

更新:我似乎有人评论说 System.IO.Packaging 命名空间对此也可能有用。有谁知道具体怎么做吗?

.net compression zip
9个回答
16
投票

MSDN 有一个完整的 example http://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage.aspx 使用 ZipPackage 类。 需要 .NET 3.5。


7
投票

其他答案已经过时了十年。

.NET 4.5 对 System.IO.Compression 添加了广泛的改进。

它现在可以很好地操作 .zip 文件,甚至可以将 zip 中的各个文件公开为能够读取或写入的流,而无需提取和压缩文件的步骤。

全部内置,不再需要第三方库。

例如:

using System;
using System.IO.Compression;

class Program
{
    static void Main(string[] args)
    {
        string startPath = @".\start";
        string zipPath = @".\result.zip";
        string extractPath = @".\extract";

        ZipFile.CreateFromDirectory(startPath, zipPath);

        ZipFile.ExtractToDirectory(zipPath, extractPath);
    }
}

6
投票

戴夫,非常好!我不知道那里有。

现在我知道要寻找什么了,我找到了一篇文章,其中包含有关如何使用它的小代码示例: http://weblogs.asp.net/jgalloway/archive/2007/10/25/creating-zip-archives-in-net-without-an-external-library-like-sharpziplib.aspx

在相关说明中,我还发现了 DotNetZip 项目,它看起来非常易于使用。


6
投票

您将需要使用第三方库,例如 http://www.codeplex.com/DotNetZip,而不是尝试使用 GZipStream 或 DeflateStream 来读取 zip 文件。

.NET 中的 ***Stream 类可以让您读取或写入压缩字节流。 这些类不读取或写入 zip 文件。 zip 文件是由“信封”或标头包围的压缩数据。 将其视为元数据 - 它包括文件名、时间戳、CRC 和一堆其他内容。 **Stream 类仅生成压缩数据流,不知道如何生成或使用元数据,这在 PKWare 维护的 PKZip 格式规范中进行了描述。

DotNetZip 等第三方库处理 ZIP 存档中的元数据。他们可能会也可能不会使用 System.IO. Compression.DeflateStream() 类来生成压缩的字节流。 例如,在以前的版本中,DotNetZip 使用内置的 DeflateStream。 从 v1.7 开始,DotNetZip 包含了自己的 DeflateStream,它比 .NET Framework 中提供的 DeflateStream 更高效。 作为一个额外的好处,DotNetZip 中嵌入的 DeflateStream 允许在 .NET Compact Framework 2.0 上使用 DotNetZip,该框架缺少 System.IO.Compression.DeflateStream。 (Compact Framework 3.5 中添加)

如果您有更多问题,DotNetZip 网站上有一个很好的论坛。 C# 代码示例:

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

6
投票

自 .NET 4.5 起,Microsoft 向 System.IO.Compression 命名空间提供了

ZipArchive
类。 不过,与该命名空间中的其他类不同,如
GZipStream
Deflate
流,
ZipArchive
需要引用 System.IO.Compression.dll 程序集。

使用起来相当简单,上面的 MSDN 链接提供了一些很好的示例。

此外,Microsoft 还创建了 Microsoft Compression NuGet 包,它向 Windows Phone 8 和其他可移植类库添加了对

ZipArchive
及相关类的支持



1
投票

一个旧线程,但我想分享我发现的最简单的解决方案,仅在一行代码中使用 System.IO.Compression(读/写):

System.IO.Compression.ZipFile.ExtractToDirectory(sourceArchiveFileName, destinationDirectoryName);
System.IO.Compression.ZipFile.CreateFromDirectory(directoryToArchivePath, archiveDestinationPath);

0
投票

是的,我过去用过它。 我对 DataSet 进行了一次子类化,以支持将其自身持久保存到文件中(通过 ReadXML/WriteXML 方法)。 作为额外的好处,我决定允许它根据需要进行选择性压缩(正如大家都应该知道的那样,这对于 XML 等文本数据非常有效)。

我使用了 GZipStream 类(据我当时的理解,相关的 DeflateStream 只是没有头信息的 GZip,或者类似的东西 - 我相信有人可以纠正我)。 它的工作原理非常简单,只需在另一个流的顶部搭载即可,因此您可以使用 GZipStream 代替它。 就我而言,它是搭载在 FileStream 上的。

给定一个 MemoryStream 来填充

myDataSet.WriteXML()
的输出,我做了如下操作:

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

其中

Save()
Pump()
是如下简单方法:

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

0
投票
    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);
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.