Pergunta

Eu tenho um DataSet que consiste em dados XML, eu posso facilmente saída a um arquivo:

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

No entanto o que eu quero fazer é comprimir o XML em um ZIP ou outro tipo de arquivo compactado e, em seguida, basta salvar este arquivo em disco, enquanto dividindo o arquivo ZIP em pedaços de 1MB. Eu realmente não deseja salvar o arquivo descompactado, e depois fechá-lo, então dividi-lo.

O que eu estou procurando especificamente é:

  1. uma biblioteca de compressão adequado que eu possa transmitir o XML para e ter o arquivo zip (s) salvos no disco
  2. algum código C # exemplo que pode me mostrar como fazer isso.
Foi útil?

Solução

Eu consegui comprimir fluxo XML de um DataSet usando compressão gzip .NET 2.0.

Aqui está o post que eu fiz há alguns anos atrás sobre isso:

Salvando DataSets localmente com compressão

... e aqui está o código que eu adicionei à minha classe parcial do DataSet para gravar o arquivo compactado (o post tem o código de leitura também):

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

Note que este código usa diferentes esquemas de compressão com base na extensão do arquivo. Que era puramente para que eu pudesse testar um esquema contra o outro com o meu DataSet.

Outras dicas

Há uma API embalagem não tão bem conhecido incluído no quadro 3.5. A referência Assembleia está no GAC, chamado WindowsBase. O namespace System.IO.Packaging contém material para a criação de arquivos OPC (por exemplo OOXML), que são arquivos zip contendo XML e tudo aquilo que é desejado. Você ganha algum material extra que você não precisa, mas a classe ZipPackage usa uma interface de streaming para adicionar conteúdo de forma iterativa.

Isso funciona com streams ou arquivos, tem uma licença bom e fonte: http://www.codeplex.com / DotNetZip

Aqui está o código para fazer exatamente o que o poster original perguntou: escrever um DataSet em um zip que é dividida em pedaços 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);
}

quadro inclui algumas aulas para comprimir córregos. Um deles é GZipStream. Se você procurar por ele você vai descobrir uma abundância de hits. Aqui está um deles. Imagino chunking a saída seria envolver algum algum trabalho adicional.

Você deve usar Xceed Zip . O código ficaria assim (não testado):

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 faz compressão zip, através de fluxos, mas não faz arquivos zip de multi-parte. : (

Editar :. A partir de setembro de 2009, DotNetZip pode fazer arquivos zip várias partes

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top