Base de Conhecimento

Compactar ou descompactar arquivos usando C# - Compressão e descompressão de arquivos

O que é ZIP (Formato de arquivo)

ZIP é um formato de arquivo de arquivamento que suporta compressão de dados sem perdas. Um arquivo ZIP pode conter um ou mais arquivos ou diretórios que foram comprimidos. Arquivos ZIP geralmente utilizam as extensões .zip ou .ZIP e o tipo MIME application/zip. ZIP é usado como formato base por muitos programas, geralmente sob um nome diferente. Ao navegar em um sistema de arquivos por meio de uma interface gráfica, ícones que representam arquivos ZIP costumam aparecer como um documento ou outro objeto destacando visualmente um zíper.

Existem várias maneiras de compactar (comprimir) arquivos , dependendo do sistema operacional que você usa. E quase todos os dias precisamos compactar ou descompactar alguns arquivos e enviá‑los para um servidor de armazenamento ou plataforma de compartilhamento de arquivos. Felizmente, podemos automatizar esse processo usando a Aspose.ZIP API . Ela permite comprimir e descomprimir arquivos sem se preocupar com a estrutura subjacente. Este artigo mostra como trabalhar com compressão de um único arquivo e de múltiplos arquivos.

Aspose.ZIP package can be added to your .NET project using the following NuGet command:

PM> Install-Package Aspose.Zip

Como compactar um único arquivo com C#

  1. Primeiro, precisamos criar um objeto da classe FileStream para o arquivo ZIP de saída.
  2. Carregar um único arquivo no objeto FileStream .
  3. Criar um objeto da classe Archive .
  4. Adicionar o arquivo ao arquivo usando Archive.CreateEntry (“FileName”, FileStream).
  5. Criar o arquivo ZIP usando Archive.Save (FileStream).
        using (FileStream zipFile = File.Open(dataDir + "CompressSingleFile_out.zip", FileMode.Create))
        {
            //File to be added to archive
            using (FileStream source1 = File.Open(dataDir + "alice29.txt", FileMode.Open, FileAccess.Read))
            {
                    using (var archive = new Archive(new ArchiveEntrySettings()))
                {
                    archive.CreateEntry("alice29.txt", source1);
                    archive.Save(zipFile);
                }
            }
        }

Compactando vários arquivos com C#

A diferença entre compactar um único arquivo e vários arquivos é que precisamos carregar mais arquivos no FileStream e adicioná‑los todos ao arquivo ZIP usando o método Archive.CreateEntry("FileName", FileStream).

O trecho de código a seguir demonstra como adicionar vários arquivos ao ZIP usando FileStream.

        // Create FileStream for output ZIP archive
        using (FileStream zipFile = File.Open("compressed_files.zip", FileMode.Create))
        {
	        // File to be added to archive
	        using (FileStream source1 = File.Open("alice29.txt", FileMode.Open, FileAccess.Read))
	            {
		            // File to be added to archive
		            using (FileStream source2 = File.Open("asyoulike.txt", FileMode.Open, FileAccess.Read))
		        {
			        using (var archive = new Archive())
			            {
				            // Add files to the archive
				            archive.CreateEntry("alice29.txt", source1);
				            archive.CreateEntry("asyoulik3.txt", source2);
				            // ZIP the files
				            archive.Save(zipFile, new ArchiveSaveOptions() { Encoding = Encoding.ASCII, ArchiveComment = "two files are compressed in this archive" });
		            	}
		        }
	        }
        }

Compactar arquivos usando a classe FileInfo

Arquivos também podem ser carregados usando a classe FileInfo e, em seguida, adicionados ao arquivo ZIP da mesma forma que antes.

A classe FileInfo fornece propriedades e métodos de instância para criação, cópia, exclusão, movimentação e abertura de arquivos, além de auxiliar na criação de objetos FileStream.

    using (FileStream zipFile = File.Open("compressed_files.zip", FileMode.Create))
    {
	    // Files to be added to archive
	    FileInfo fi1 = new FileInfo("alice29.txt");
	    FileInfo fi2 = new FileInfo("fields.c");
	    using (var archive = new Archive())
	        {
		        // Add files to the archive
		        archive.CreateEntry("alice29.txt", fi1);
		        archive.CreateEntry("fields.c", fi2);
		        // Create ZIP archive
		        archive.Save(zipFile, new ArchiveSaveOptions() { Encoding = Encoding.ASCII });
	        }
    }

Armazenar arquivos em arquivos ZIP sem compressão

    //Creates zip archive without compressing files
    using (FileStream zipFile = File.Open(dataDir + "StoreMultipleFilesWithoutCompression_out.zip", FileMode.Create))
    {
    FileInfo fi1 = new FileInfo(dataDir + "alice29.txt");
    FileInfo fi2 = new FileInfo(dataDir + "lcet10.txt");

    using (Archive archive = new Archive(new ArchiveEntrySettings(new StoreCompressionSettings())))
    {
        archive.CreateEntry("alice29.txt", fi1);
        archive.CreateEntry("lcet10.txt", fi2);
        archive.Save(zipFile, new ArchiveSaveOptions() { Encoding = Encoding.ASCII });
    }
    }  

Como compactar arquivos ZIP com senha em C#

    using (var archive = new Archive(new ArchiveEntrySettings(encryptionSettings: new TraditionalEncryptionSettings("pass"))))
    {
    archive.CreateEntry("entry_name1.dat", "input_file1.dat");
    archive.CreateEntry("entry_name2.dat", "input_file2.dat");
    archive.Save("result_archive.zip");
    }

O parâmetro encryptionSettings é usado para criar um arquivo ZIP protegido por senha.

Como descompactar arquivos ZIP com senha em C#

    using (var archive = new Archive("input_archive.zip", new ArchiveLoadOptions{DecryptionPassword = "pass"}))
    {
    archive.ExtractToDirectory("\\outputDirectory");
    }

A propriedade DecryptionPassword em ArchiveLoadOptions é usada para abrir um arquivo ZIP protegido por senha.

Para ver exemplos completos e arquivos de dados, visite https://github.com/aspose-zip/Aspose.ZIP-for-.NET .

Usando compressão LZMA dentro de um arquivo ZIP

O algoritmo Lempel–Ziv–Markov chain (LZMA) é usado para realizar compressão de dados sem perdas. LZMA utiliza um algoritmo de compressão por dicionário, produzindo um fluxo de bits comprimido. A compressão LZMA dentro de um arquivo ZIP permite que contêineres ZIP contenham entradas comprimidas com LZMA. O exemplo de código a seguir demonstra a implementação da compressão LZMA usando a Aspose.ZIP API .

using (FileStream zipFile = File.Open(dataDir + "LZMACompression_out.zip", FileMode.Create))
{
    using (Archive archive = new Archive(new ArchiveEntrySettings(new LzmaCompressionSettings())))
    {
        archive.CreateEntry("sample.txt", dataDir + "sample.txt");
        archive.Save(zipFile);
    }
}

Usando compressão BZip2 dentro de um arquivo ZIP

bzip2 é um programa gratuito e de código aberto para compressão de arquivos que utiliza o algoritmo de Burrows–Wheeler. Ele comprime apenas arquivos individuais e não funciona como um arquivador de múltiplos arquivos. Foi desenvolvido por Julian Seward e mantido por Mark Wielaard e Micah Snyder. O trecho de código a seguir demonstra a implementação da compressão BZip2 usando a Aspose.ZIP API .

using (FileStream zipFile = File.Open(dataDir + "Bzip2Compression_out.zip", FileMode.Create))
{
    using (Archive archive = new Archive(new ArchiveEntrySettings(new Bzip2CompressionSettings())))
    {
        archive.CreateEntry("sample.txt", dataDir + "sample.txt");
        archive.Save(zipFile);
    }
}

Usando compressão PPMd dentro de um arquivo ZIP

Prediction by partial matching (PPM) é uma técnica adaptativa de compressão estatística baseada em modelagem de contexto e predição. Modelos PPM utilizam um conjunto de símbolos anteriores no fluxo de símbolos não comprimidos para prever o próximo símbolo. Algoritmos PPM também podem ser usados para agrupar dados em agrupamentos previstos em análises de cluster. O trecho de código a seguir demonstra a implementação da compressão PPMd usando a Aspose.ZIP API .

using (FileStream zipFile = File.Open(dataDir + "PPMdCompression_out.zip", FileMode.Create))
{
    using (Archive archive = new Archive(new ArchiveEntrySettings(new PPMdCompressionSettings())))
    {
        archive.CreateEntry("sample.txt", dataDir + "sample.txt");
        archive.Save(zipFile);
    }
}

Descompactar arquivo com um único arquivo

using (FileStream fs = File.OpenRead(dataDir + "CompressSingleFile_out.zip"))
{
    using (Archive archive = new Archive(fs))
    {
        int percentReady = 0;
        archive.Entries[0].ExtractionProgressed += (s, e) =>
        {
            int percent = (int)((100 * e.ProceededBytes) / ((ArchiveEntry)s).UncompressedSize);
            if (percent > percentReady)
            {
                Console.WriteLine(string.Format("{0}% decompressed", percent));
                percentReady = percent;
            }
        };
        archive.Entries[0].Extract(dataDir + "alice_extracted_out.txt");
    }
}

Descompactar arquivo com vários arquivos

using (FileStream zipFile = File.Open(dataDir + "CompressMultipleFiles_out.zip", FileMode.Open))
{
    StringBuilder sb = new StringBuilder("Entries are: ");
    int percentReady = 0;
    using (Archive archive = new Archive(zipFile,
        new ArchiveLoadOptions()
        {
            EntryListed = (s, e) => { sb.AppendFormat("{0}, ", e.Entry.Name); },
            EntryExtractionProgressed = (s, e) =>
            {
                int percent = (int)((100 * e.ProceededBytes) / ((ArchiveEntry)s).UncompressedSize);
                if (percent > percentReady)
                {
                    Console.WriteLine(string.Format("{0}% compressed", percent)); percentReady = percent;
                }
            }
        }))
    {
        Console.WriteLine(sb.ToString(0, sb.Length - 2));
        using (var extracted = File.Create(dataDir + "alice_extracted_out.txt"))
        {
            using (var decompressed = archive.Entries[0].Open())
            {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while (0 < (bytesRead = decompressed.Read(buffer, 0, buffer.Length)))
                {
                    extracted.Write(buffer, 0, bytesRead);
                }
                // Read from decompressed stream to extracting file.
            }
        }
        percentReady = 0;
        archive.Entries[1].Extract(dataDir + "asyoulik_extracted_out.txt");
    }
}

Extrair arquivo armazenado sem compressão

using (FileStream zipFile = File.Open(dataDir + "StoreMultipleFilesWithoutCompression_out.zip", FileMode.Open))
{
    using (Archive archive = new Archive(zipFile))
    {
        using (var extracted = File.Create(dataDir + "alice_extracted_store_out.txt"))
        {
            using (var decompressed = archive.Entries[0].Open())
            {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while (0 < (bytesRead = decompressed.Read(buffer, 0, buffer.Length)))
                {
                    extracted.Write(buffer, 0, bytesRead);
                }
                // Read from decompressed stream to extracting file.
            }
        }

        using (var extracted = File.Create(dataDir + "asyoulik_extracted_store_out.txt"))
        {
            using (var decompressed = archive.Entries[1].Open())
            {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while (0 < (bytesRead = decompressed.Read(buffer, 0, buffer.Length)))
                {
                    extracted.Write(buffer, 0, bytesRead);
                }
                // Read from decompressed stream to extracting file.
            }
        }
    }
}

Para ver exemplos completos e arquivos de dados, visite https://github.com/aspose-zip/Aspose.ZIP-for-.NET .