Muitas vezes, você obtém um arquivo ZIP que contém outros arquivos ZIP dentro dele, formando uma estrutura aninhada dos arquivos. Nesses casos, você pode querer obter uma estrutura plana extraindo todos os arquivos ZIP internos para o arquivo externo. Para executar essa operação programaticamente, este artigo mostra como criar um arquivo ZIP simples em C#.

API C# .NET para criar arquivos ZIP simples

Para criar os arquivos ZIP simples, usaremos Aspose.ZIP for .NET. É uma API de arquivamento projetada para criar e extrair formatos de arquivo populares, incluindo ZIP, TAR, GZip e 7z. Você pode instalar a API de NuGet ou baixar sua DLL da seção de downloads.

PM> Install-Package Aspose.Zip

Criar um arquivo ZIP plano em C#

Para entender a estrutura de um arquivo ZIP simples, vamos dar um exemplo. O seguinte é um arquivo ZIP que contém outro arquivo ZIP dentro dele.

parent.zip
 ├first.txt
 ├inner.zip
 │ ├game.exe
 │ └subitem.bin
 └picture.gif

Depois de transformar esse arquivo ZIP em um ZIP simples, todas as entradas do ZIP interno serão extraídas para o ZIP pai. Por fim, obteremos a seguinte estrutura do ZIP pai.

flatten.zip
 ├first.txt
 ├picture.gif
 ├game.exe
 └subitem.bin

Vamos ver como realizar essa transformação programaticamente. A seguir estão as etapas para criar um arquivo ZIP simples em C#.

  • Primeiro, carregue o arquivo ZIP pai usando a classe Archive.
  • Em seguida, crie listas para armazenar as entradas ZIP internas para excluir do ZIP pai, entradas extraídas e seus nomes.
  • Depois disso, percorra cada ArchiveEntry no ZIP pai usando a coleção Archive.Entries.
  • Para cada entrada, execute as seguintes operações:
    • Verifique se a entrada é um arquivo ZIP usando o método ArchiveEntry.Name.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)).
    • Em seguida, adicione a entrada à lista de entradas a serem excluídas.
    • Abra a entrada em um objeto MemoryStream usando o método ArchiveEntry.Open().CopyTo(MemoryStream).
    • Itere pelas entradas do arquivo ZIP interno e em cada iteração, execute as etapas a seguir.
      • Adicione o nome da entrada na lista de entradas a serem adicionadas.
      • Em seguida, carregue a entrada para MemoryStream usando o método ArchiveEntry.Open().CopyTo(MemoryStream).
      • Por fim, adicione a entrada à lista de entradas a serem adicionadas ao ZIP pai.
  • Em seguida, percorra a lista de arquivos ZIP internos e exclua cada entrada usando o método Archive.DeleteEntry(ArchiveEntry).
  • Percorra a lista de entradas a serem adicionadas ao ZIP pai e adicione cada entrada usando o método Archive.CreateEntry(String, Stream).
  • Finalmente, salve o arquivo ZIP pai usando o método Archive.Save(String).

O exemplo de código a seguir mostra como criar um arquivo ZIP simples em C#.

// Carregar arquivo ZIP
using (Archive outer = new Archive("Archives/nested-archive.zip"))
{
    // Crie uma lista para excluir entradas ZIP internas após a extração
    List<ArchiveEntry> entriesToDelete = new List<ArchiveEntry>();

    // Crie uma lista para adicionar nomes de arquivos em arquivos ZIP internos
    List<string> namesToInsert = new List<string>();

    // Crie uma lista para adicionar objetos de fluxo de arquivos em arquivos ZIP internos
    List<MemoryStream> contentToInsert = new List<MemoryStream>();

    // Percorrer as entradas no ZIP pai
    foreach (ArchiveEntry entry in outer.Entries)
    {
        // Verifique se a entrada é um arquivo ZIP
        if (entry.Name.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) 
        {
            // Adicionar entrada à lista para manter a referência e removê-la do arquivo posteriormente
            entriesToDelete.Add(entry); 

            // Criar objeto de fluxo para abrir o arquivo ZIP
            MemoryStream innerCompressed = new MemoryStream();
            entry.Open().CopyTo(innerCompressed);

            // Carregar o arquivo ZIP do objeto stream 
            using (Archive inner = new Archive(innerCompressed))
            {
                // Faça um loop sobre as entradas do arquivo
                foreach (ArchiveEntry ie in inner.Entries) 
                {
                    // Manter o nome da entrada na lista
                    namesToInsert.Add(ie.Name); 

                    // Extraia a entrada de arquivo em um objeto de fluxo
                    MemoryStream content = new MemoryStream();
                    ie.Open().CopyTo(content);

                    // Adicionar entrada à lista
                    contentToInsert.Add(content);
                }
            }
        }
    }

    // Excluir os arquivos ZIP internos
    foreach (ArchiveEntry e in entriesToDelete)
        outer.DeleteEntry(e);

    // Insira os arquivos de arquivos ZIP internos no arquivo ZIP pai
    for (int i = 0; i < namesToInsert.Count; i++)
        outer.CreateEntry(namesToInsert[i], contentToInsert[i]);

    outer.Save("Archives/flatten.zip");
}

Obtenha uma licença de API gratuita

Você pode obter uma licença temporária gratuita para usar o Aspose.ZIP para .NET sem limitações de avaliação.

Conclusão

Neste artigo, você aprendeu como criar um arquivo ZIP simples programaticamente em C#. Particularmente, demonstramos como fazer um ZIP simples extraindo os arquivos ZIP internos no ZIP pai. Além disso, você pode visitar a documentação para ler mais sobre o Aspose.ZIP para .NET. Além disso, você pode compartilhar suas dúvidas conosco através do nosso fórum.

Veja também