【问题标题】:.NET - Stream DataSet (of XML data) to ZIP file?.NET - 将数据集(XML 数据)流式传输到 ZIP 文件?
【发布时间】:2008-10-21 22:17:29
【问题描述】:

我有一个由 XML 数据组成的 DataSet,我可以轻松地将其输出到文件中:

DataSet ds = new DataSet();
DataTable dt = new DataTable();
ds.Tables.Add(dt);
ds.Load(reader, LoadOption.PreserveChanges, ds.Tables[0]);
ds.WriteXml("C:\\test.xml");

但是我想要做的是将 XML 压缩成 ZIP 或其他类型的压缩文件,然后将此文件保存到磁盘,同时将 ZIP 文件拆分为 1MB 块。我真的不想保存未压缩的文件,然后将其压缩,然后拆分。

我正在寻找的具体是:

  1. 一个合适的压缩库,我可以将 XML 流式传输到并将 zip 文件保存到磁盘
  2. 一些示例 C# 代码可以告诉我如何执行此操作。

【问题讨论】:

    标签: c# compression zip


    【解决方案1】:

    我已经设法使用 .NET 2.0 的 gzip 压缩来压缩 DataSet 的 XML 流。

    这是我几年前写的关于它的博客文章:

    Saving DataSets Locally With Compression

    ...这是我添加到我的 DataSet 的部分类以编写压缩文件的代码(博客文章也有阅读代码):

    public void WriteFile(string fileName)
    {
        using (FileStream fs = new FileStream(fileName, FileMode.Create))
        {
            Stream s;
            if (Path.GetExtension(fileName) == ".cmx")
            {
                s = new GZipStream(fs, CompressionMode.Compress);
            }
            else if (Path.GetExtension(fileName) == ".cmz")
            {
                s = new DeflateStream(fs, CompressionMode.Compress);
            }
            else
            {
                s = fs;
            }
            WriteXml(s);
            s.Close();
        }
    } 
    

    请注意,此代码根据文件的扩展名使用不同的压缩方案。这纯粹是为了让我可以用我的 DataSet 对另一种方案进行测试。

    【讨论】:

      【解决方案2】:

      3.5 框架中包含一个不太知名的打包 API。程序集引用位于 GAC 中,称为 WindowsBase。 System.IO.Packaging 命名空间包含用于创建 OPC 文件(例如 OOXML)的内容,这些文件是包含 xml 和其他任何所需内容的 zip 文件。你会得到一些你不需要的额外东西,但是 ZipPackage 类使用流接口来迭代地添加内容。

      【讨论】:

        【解决方案3】:

        这适用于流或文件,具有良好的许可证和来源:http://www.codeplex.com/DotNetZip

        这里的代码完全按照原始发帖人的要求:将 DataSet 写入一个 zip 中,该 zip 被分成 1mb 块:

        // get connection to the database
        var c1= new System.Data.SqlClient.SqlConnection(connstring1);
        var da = new System.Data.SqlClient.SqlDataAdapter()
        {
            SelectCommand= new System.Data.SqlClient.SqlCommand(strSelect, c1)
        };
        
        DataSet ds1 = new DataSet();
        
        // fill the dataset with the SELECT 
        da.Fill(ds1, "Invoices");
        
        // write the XML for that DataSet into a zip file (split into 1mb chunks)
        using(Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
        {
            zip.MaxOutputSegmentSize = 1024*1024;
            zip.AddEntry(zipEntryName, (name,stream) => ds1.WriteXml(stream) );
            zip.Save(zipFileName);
        }
        

        【讨论】:

        • 截至 2009 年 9 月,DotNetZip 可以读取或写入“跨区”ZIP 文件。如果要创建拆分或跨区 zip,请在保存之前指定每个段的大小限制。然后你会得到 N 个文件,每个文件都有你指定的大小。
        【解决方案4】:

        该框架包括一些用于压缩流的类。其中之一是 GZipStream。如果你搜索它,你会发现很多命中。这是其中的one。我想分块输出会涉及一些额外的工作。

        【讨论】:

          【解决方案5】:

          您应该使用Xceed Zip。代码看起来像这样(未经测试):

          ZipArchive archive = new ZipArchive( new DiskFile( @"c:\path\file.zip" ) );
          
          archive.SplitSize = 1024*1024;
          archive.BeginUpdate();
          
          try
          {
            AbstractFile destFile = archive.GetFile( "data.xml" );
          
            using( Stream stream = destFile.OpenWrite( true ) )
            {
              ds.WriteXml( stream );
            }
          }
          finally
          {
            archive.EndUpdate();
          }
          

          【讨论】:

            【解决方案6】:

            DotNetZip 通过流进行 zip 压缩,但不进行多部分 zip 文件。 :(

            编辑:截至 2009 年 9 月,DotNetZip 可以处理多部分 zip 文件。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-08-07
              • 2021-02-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-09
              相关资源
              最近更新 更多