【问题标题】:How to use System.IO.Compression to read/write ZIP files?如何使用 System.IO.Compression 读取/写入 ZIP 文件?
【发布时间】:2010-09-16 02:33:04
【问题描述】:

我知道有libraries out there for working with ZIP files。而且,您也可以use the functionality built into Windows for working ZIP files

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

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

【问题讨论】:

    标签: .net compression zip


    【解决方案1】:

    自 .NET 4.5 起,Microsoft 已将 ZipArchive 类提供给 System.IO.Compression 命名空间。不过,与该命名空间中的其他类不同,例如GZipStreamDeflate 流,ZipArchive 需要引用 System.IO.Compression.dll 程序集。

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

    此外,Microsoft 还创建了Microsoft Compression NuGet package,它为 Windows Phone 8 和其他便携式类库添加了对ZipArchive 和相关类的支持

    【讨论】:

      【解决方案2】:

      我知道,这是一个较旧的线程,但我想指出,.NET 4.5 对 system.io.compression 进行了广泛的改进。它现在可以很好地操作 .zip 文件,甚至可以将 zip 中的单个文件公开为能够读取和写入的流,而无需提取和压缩文件的步骤。

      【讨论】:

        【解决方案3】:
            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);
                }
            }
        

        【讨论】:

          【解决方案4】:

          您将希望使用第三方库,例如 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 中提供的更高效。作为一个额外的好处,DotNetZip 中的嵌入式 DeflateStream 允许 DotNetZip 在缺少 System.IO.Compression.DeflateStream 的 .NET Compact Framework 2.0 上使用。 (它是在 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);
              }
          

          【讨论】:

            【解决方案5】:

            是的,我以前用过。我将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);
            }
            

            【讨论】:

            • 您的解决方案不会读取或写入 ZIP 文件格式,而只是读取或写入原始 deflate 压缩,或围绕 deflate 压缩的 GZip 简单页眉-页脚扩展。
            • +1 您的答案可能不会创建 ZIP 文件,但它确实展示了如何使用 System.IO.Compression,这对于压缩 SSIS 中的文件非常有用,您只能使用 .NET 2.0,它是很难使用外部库。
            【解决方案6】:
            【解决方案7】:

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

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

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

            【讨论】:

              【解决方案8】:

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

              【讨论】:

              • 实际上,System.IO.Packaging-namespace 包含用于处理 Open Packaging 样式包的类。您可以使用它来创建 ZIP 文件(如果您不关心将包含在 ZIP 中的一些额外文件),但它不能用于打开 任何 zip 文件。有关更多信息,请参阅 bottom of ZipPackage class documentation(此社区在 .NET 4.0 文档中不存在,但仍然有效)。
              猜你喜欢
              • 2019-04-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-21
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多