Domanda

Ho un DataSet costituito da dati XML, posso facilmente inviarlo in un file:

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");

Tuttavia, ciò che voglio fare è comprimere l'XML in un ZIP o altro tipo di file compresso e quindi salvare questo file su disco mentre si divide il file ZIP in blocchi da 1 MB. Non voglio davvero salvare il file non compresso, quindi comprimerlo, quindi dividerlo.

Quello che sto cercando specificamente è:

  1. una libreria di compressione adatta su cui posso trasmettere l'XML e salvare i file zip su disco
  2. alcuni esempi di codice C # che può mostrarmi come fare.
È stato utile?

Soluzione

Sono riuscito a comprimere il flusso XML di un DataSet usando la compressione gzip di .NET 2.0.

Ecco il post sul blog che ho scritto alcuni anni fa al riguardo:

Salvataggio di set di dati localmente con compressione

... ed ecco il codice che ho aggiunto alla classe parziale del mio DataSet per scrivere il file compresso (anche il post del blog ha il codice di lettura):

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

Nota che questo codice usa diversi schemi di compressione basati sull'estensione del file. Questo è stato puramente per poter testare uno schema contro l'altro con il mio DataSet.

Altri suggerimenti

Esiste un'API di packaging non così nota inclusa nel framework 3.5. Il riferimento dell'Assemblea è nel GAC, chiamato WindowsBase. Lo spazio dei nomi System.IO.Packaging contiene elementi per la creazione di file OPC (ad esempio OOXML), che sono file zip contenenti xml e qualsiasi altra cosa si desideri. Ottieni alcune cose extra che non ti servono, ma la classe ZipPackage utilizza un'interfaccia di streaming per aggiungere contenuti in modo iterativo.

Funziona con flussi o file, ha una buona licenza e fonte: http://www.codeplex.com / DotNetZip

Ecco il codice per fare esattamente ciò che il poster originale ha chiesto: scrivere un DataSet in uno zip che è diviso in blocchi da 1 MB:

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

il framework include alcune classi per comprimere i flussi. Uno di questi è GZipStream. Se lo cerchi troverai molti successi. Eccone uno . Immagino che ridimensionare l'output comporterebbe qualche lavoro aggiuntivo.

Devi utilizzare Xceed Zip . Il codice sarebbe simile al seguente (non testato):

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 esegue la compressione zip, tramite flussi, ma non fa file zip in più parti. : (

MODIFICA : a partire da settembre 2009, DotNetZip può creare file zip in più parti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top