.NET - Поток DataSet (XML-данных) в ZIP-файл? - PullRequest
8 голосов
/ 22 октября 2008

У меня есть DataSet, состоящий из данных 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-файл на куски по 1 МБ. Я не хочу сохранять несжатый файл, а затем сжать его, а затем разделить.

Что я конкретно ищу:

  1. подходящая библиотека сжатия, в которую я могу передавать поток XML-файлов и сохранять zip-файлы на диске
  2. пример кода C #, который может показать мне, как это сделать.

Ответы [ 6 ]

10 голосов
/ 22 октября 2008

Мне удалось сжать XML-поток DataSet с помощью сжатия gzip в .NET 2.0.

Вот сообщение в блоге, которое я сделал несколько лет назад об этом:

Локальное сохранение наборов данных со сжатием

... и вот код, который я добавил в частичный класс моего 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 голосов
/ 22 октября 2008

Существует не очень известный API упаковки, включенный в 3.5. Ссылка на сборку находится в GAC, называется WindowsBase. Пространство имен System.IO.Packaging содержит материал для создания OPC-файлов (например, OOXML), которые представляют собой zip-файлы, содержащие xml и все, что требуется. Вы получаете дополнительные вещи, которые вам не нужны, но класс ZipPackage использует потоковый интерфейс для итеративного добавления контента.

2 голосов
/ 22 октября 2008

Работает с потоками или файлами, имеет хорошую лицензию и источник: http://www.codeplex.com/DotNetZip

Вот код, чтобы сделать именно то, о чем просил оригинальный автор: записать DataSet в zip-файл, разбитый на куски по 1 МБ:

// 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);
}
1 голос
/ 22 октября 2008

Вы должны использовать 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();
}
1 голос
/ 22 октября 2008

фреймворк включает в себя несколько классов для сжатия потоков. Одним из них является GZipStream. Если вы ищете его, вы найдете много хитов. Вот один из них. Я полагаю, что фрагментация результата потребует некоторой дополнительной работы.

0 голосов
/ 09 марта 2009

DotNetZip выполняет сжатие zip через потоки, но не выполняет многослойные zip файлы. (

РЕДАКТИРОВАТЬ : по состоянию на сентябрь 2009 года DotNetZip может создавать многоцелевые zip-файлы.

...