C# -  Compactando e Descompactando na memória


Hoje veremos como compactar e descompactar arquivos na memória usando a classe GZipStream e métodos de extensão.

Geralmente quando realizamos alguma compactação na memória de uma grande quantidade de texto armazenamos  o resultado em um arquivo ou banco de dados. 

No entanto podemos também enviar o arquivo compactado via email como um anexo para que o destinatário possa receber e descompactar.

Seja qual for o motivo, a compactação e descompactação na memória é um recurso muito útil, e, uma forma bem simples de realizar esta tarefa é usar métodos de extensão.

O namespace namespace System.IO.Compression da contém classes para compactar e descompactar streams (arquivos, sequências de caracteres, bytes, etc) fornecendo recursos para realizar tais tarefas de forma bem simples.

Neste namespace destacamos a classe GZipStream fornece métodos e propriedades usadas para compactar e descompactar streams.

Vejamos como fazer isso funcionar...

Crie um novo projeto do tipo Console (.NET Core) no VS 2019 chamado Demo1

No projeto crie uma classe chamada ExtensionMethods e defina os métodos CompressStream e DecompressStream:

using System.IO;
using System.IO.Compression;

namespace Demo1
{
    public static class ExtensionMethods
    {
        public static byte[] CompressStream(this byte[] originalSource)
        {
            using (var outStream = new MemoryStream())
            {
                using (var gzip = new GZipStream(outStream, CompressionMode.Compress))
                {
                    gzip.Write(originalSource, 0, originalSource.Length);
                }
                return outStream.ToArray();
            }
        }
        public static byte[] DecompressStream(this byte[] originalSource)
        {
            using (var sourceStream = new MemoryStream(originalSource))
            {
                using (var outStream = new MemoryStream())
                {
                    using (var gzip = new GZipStream(sourceStream, CompressionMode.Decompress))
                    {
                        gzip.CopyTo(outStream);
                    }
                    return outStream.ToArray();
                }
            }
        }
    }
}

Nota : Se você não sabe como funcionam os métodos de extensão veja este meu artigo: Métodos de Extensão

Agora suponha que em uma pasta do seu sistema local existe um arquivo chamado ArquivoDemo.txt.

Vamos definir o código na classe Program para ler este arquivo e realizar a compactação e descompactação na memória usando os métodos de extensão criados acima:

using static System.Console;
using System.IO;
using System.Text;
using Demo1;

string arquivoGrande = @"C:\dados\txt\ArquivoDemo.txt";

string arquivoLido = File.ReadAllText(arquivoGrande);
var bytes = Encoding.Default.GetBytes(arquivoLido);

var tamanhoOriginal = bytes.Length;
var compactado = bytes.CompressStream();
var tamanhoCompactado = compactado.Length;

var novoArquivoDescompactado = compactado.DecompressStream();
var tamanhoNovoArquivo = novoArquivoDescompactado.Length;

WriteLine($"Tamanho do Arquivo Original   = {tamanhoOriginal}");
WriteLine($"Tamanho do Arquivo Compactado = {tamanhoCompactado}");
WriteLine($"Tamanho do Novo Arquivo Compactado = {tamanhoNovoArquivo}");

ReadLine();

No código acima estou usando o novo recurso Top Level Statements do C# 9.0.

Executando o projeto temos o seguinte resultado :

A compactação e descompactação na memória permite usar compactação e  descompressão dinâmica ao trabalhar com arquivos grandes. Isso pode ser útil quando você precisa ler e gravar informações de log em um banco de dados.

Pegue o código do projeto aqui:  Demo1.zip

"Se o SENHOR não edificar a casa, em vão trabalham os que a edificam; se o SENHOR não guardar a cidade, em vão vigia a sentinela."
Salmos 127:1

Referências:


José Carlos Macoratti