8

我有一个由 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# 代码可以向我展示如何执行此操作。
4

6 回答 6

10

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

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

使用压缩在本地保存数据集

...这是我添加到我的 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 对另一种方案进行测试。

于 2008-10-21T22:25:42.520 回答
2

这适用于流或文件,具有良好的许可证和来源: 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);
}
于 2008-10-22T00:39:16.370 回答
2

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

于 2008-10-22T01:57:11.313 回答
1

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

于 2008-10-21T22:26:01.787 回答
1

您应该使用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();
}
于 2008-10-22T00:52:45.173 回答
0

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

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

于 2009-03-09T18:21:30.780 回答