O .NET já tem embutido uma facilidade para compressão de dados com algoritmo Deflate e Gzip. Neste exemplo mostrarei como compactar e descompactar dados com Deflate, mas com GzipStream o processo é o mesmo.

A princípio parece complicado realizar essa compactação utilizando streams, mas na realidade é bem simples. O DeflateStream é um wrapper stream, ele envolve um outro stream que é onde os dados serão salvos; você grava os dados no DeflateStream, o DeflateStream grava compactado no stream de destino. Para descompactar, o processo é o inverso, você lê do DeflateStream, e o DeflateStream lê do stream de origem realizando a descompactação on-the-fly.

Para exemplificar o processo, deixo aqui dois métodos, um que realiza a compactação de um array de bytes através do DeflateStream e do MemoryStream, e um que faz a descompactação.

private static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[32768];
while (true)
{
int read = input.Read(buffer, 0, buffer.Length);
if (read <= 0) return;
output.Write(buffer, 0, read);
}
}

public static byte[] Compactar(byte[] arrayOrigem)
{
byte[] arrayComprimido;
using (MemoryStream origem = new MemoryStream(arrayOrigem, false))
{
using (MemoryStream destino = new MemoryStream())
{
using (DeflateStream compress = new DeflateStream(destino, CompressionMode.Compress))
{
CopyStream(origem, compress);
}
arrayComprimido = destino.ToArray();
}
}
return arrayComprimido;
}

public static byte[] Descompactar(byte[] arrayOrigem)
{
byte[] arrayDescomprimido;
using (MemoryStream origem = new MemoryStream(arrayOrigem, false))
{
using (MemoryStream destino = new MemoryStream())
{
using (DeflateStream decompress = new DeflateStream(origem, CompressionMode.Decompress))
{
CopyStream(decompress, destino);
}
arrayDescomprimido = destino.ToArray();
}
}
return arrayDescomprimido;
}
Anúncios