.NET - (XML データの) DataSet を ZIP ファイルにストリーミングしますか?
-
03-07-2019 - |
質問
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 のチャンクに分割しながら、このファイルをディスクに保存することです。圧縮されていないファイルを保存し、圧縮してから分割することはあまりしたくありません。
私が特に探しているのは次のとおりです。
- XML をストリーミングして zip ファイルをディスクに保存できる適切な圧縮ライブラリ
- これを行う方法を示すサンプル C# コード。
解決
.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で1つのスキームを他のスキームに対してテストできました。
他のヒント
3.5 フレームワークには、あまり知られていないパッケージ化 API が含まれています。アセンブリ参照は、WindowsBase と呼ばれる GAC 内にあります。System.IO.Packaging 名前空間には、OPC ファイルを作成するためのものが含まれています (例:OOXML) は、xml とその他の必要なものを含む zip ファイルです。不要なものがいくつか追加されますが、ZipPackage クラスはコンテンツを反復的に追加するためにストリーミング インターフェイスを使用します。
これはストリームまたはファイルで動作し、適切なライセンスとソースがあります。 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);
}
フレームワークには、ストリームを圧縮するためのいくつかのクラスが含まれています。それらの1つはGZipStreamです。検索すると、たくさんのヒットが見つかります。 そのうちの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();
}
DotNetZip は、ストリームを介してzip圧縮を行いますが、マルチパートzipファイルは行いません。 :(
編集:2009年9月現在、DotNetZipはマルチパートzipファイルを実行できます。