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

时间:2008-10-21 22:17:30

标签: c# compression zip

我有一个由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#代码,可以告诉我如何执行此操作。

6 个答案:

答案 0 :(得分:10)

我已经设法使用.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测试另一个方案。

答案 1 :(得分:2)

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

以下是完成原始海报所要求的代码:将一个DataSet写入一个分为1mb块的zip:

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

答案 4 :(得分: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();
}

答案 5 :(得分:0)

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

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