Pregunta

Tengo un DataSet que consta de datos XML, puedo enviarlo fácilmente a un archivo:

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

Sin embargo, lo que quiero hacer es comprimir el XML en un ZIP u otro tipo de archivo comprimido y luego guardar este archivo en el disco mientras se divide el archivo ZIP en fragmentos de 1 MB. Realmente no quiero guardar el archivo sin comprimir, y luego comprimirlo, luego dividirlo.

Lo que estoy buscando específicamente es:

  1. una biblioteca de compresión adecuada a la que puedo transmitir el XML y tener los archivos zip guardados en el disco
  2. algunos ejemplos de código C # que pueden mostrarme cómo hacer esto.
¿Fue útil?

Solución

He logrado comprimir una secuencia XML de DataSet usando la compresión gzip de .NET 2.0.

Aquí está la publicación del blog que hice hace unos años al respecto:

Guardando conjuntos de datos localmente con compresión

... y aquí está el código que agregué a la clase parcial de mi DataSet para escribir el archivo comprimido (la publicación del blog también tiene el código de lectura):

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

Tenga en cuenta que este código utiliza diferentes esquemas de compresión según la extensión del archivo. Eso fue puramente así que pude probar un esquema con el otro con mi DataSet.

Otros consejos

Hay una API de empaquetado no tan conocida incluida con el marco 3.5. La referencia de ensamblaje está en el GAC, llamado WindowsBase. El espacio de nombres de System.IO.Packaging contiene elementos para crear archivos OPC (por ejemplo, OOXML), que son archivos zip que contienen xml y todo lo que se desee. Obtienes algunas cosas adicionales que no necesitas, pero la clase ZipPackage usa una interfaz de transmisión para agregar contenido de forma iterativa.

Esto funciona con secuencias o archivos, tiene una buena licencia y una buena fuente: http://www.codeplex.com / DotNetZip

Aquí está el código para hacer exactamente lo que pidió el póster original: escriba un DataSet en un zip que se divide en trozos de 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);
}

el marco incluye algunas clases para comprimir flujos. Uno de ellos es GZipStream. Si lo buscas, encontrarás un montón de éxitos. Aquí hay uno de ellos. Me imagino que dividir la salida implicaría algún trabajo adicional.

Debería usar Xceed Zip . El código se vería así (no probado):

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 hace compresión zip, a través de secuencias, pero no hace archivos zip de múltiples partes. :(

EDIT : a partir de septiembre de 2009, DotNetZip puede hacer archivos zip de varias partes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top