.NET-将(XML数据的)数据集流式传输到ZIP文件

本文关键字:传输 文件 ZIP 数据集 XML 数据 NET- | 更新日期: 2023-09-27 17:48:49

我有一个由XML数据组成的数据集,我可以很容易地将其输出到一个文件:

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#代码可以向我展示如何做到这一点

.NET-将(XML数据的)数据集流式传输到ZIP文件

我已经设法使用.NET 2.0的gzip压缩来压缩数据集的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();
    }
} 

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

3.5框架中包含一个众所周知的封装API。Assembly引用位于名为WindowsBase的GAC中。System.IO.Packing命名空间包含用于创建OPC文件(例如OOXML)的内容,这些文件是包含xml和其他所需内容的zip文件。您可以获得一些不需要的额外内容,但ZipPackage类使用流接口来迭代添加内容。

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

这是一个代码,可以完全按照最初的发布者的要求:将一个数据集写入一个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);
}

您应该使用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();
}

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

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

EDIT:自2009年9月起,DotNetZip可以执行多部分zip文件。