Introdução

Quando sua empresa precisa ingerir grandes lotes de notas fiscais, documentos legais ou exportações de e‑mail que chegam como arquivos ZIP ou RAR comprimidos, a abordagem tradicional é descompactá‑los no disco, abrir cada arquivo com um leitor separado e então descartar os arquivos temporários. Esse ciclo adiciona I/O custoso, complica a limpeza e transforma o manuseio de arquivos compactados aninhados em um pesadelo.

O GroupDocs.Parser para .NET elimina esses pontos de dor. Ele permite abrir um arquivo compactado diretamente, enumerar cada entrada e extrair texto bruto (e metadados) completamente na memória. Neste artigo você aprenderá a:

  • Instalar o pacote NuGet do Parser.
  • Extrair texto de um arquivo plano em uma única passagem.
  • Percorrer recursivamente arquivos ZIP/RAR aninhados.
  • Aplicar configurações de boas práticas para um processamento robusto.

Por que a Análise de Arquivo em Memória Importa

Processar arquivos compactados na memória oferece:

  • Zero arquivos temporários – sem bagunça no disco, sem arquivos deixados para trás.
  • Velocidade – evita o ciclo extra de leitura/gravação para cada entrada.
  • Escalabilidade – manipula arquivos grandes ou streams baseados em nuvem onde um sistema de arquivos pode não estar disponível.

Pré-requisitos

  • .NET 6.0 ou posterior.
  • GroupDocs.Parser para .NET (versão mais recente) – veja a licença temporária para avaliação gratuita.
  • Um arquivo ZIP ou RAR contendo documentos suportados (PDF, DOCX, TXT, etc.).

Instalação

dotnet add package GroupDocs.Parser

Adicione os namespaces necessários:

using GroupDocs.Parser;
using GroupDocs.Parser.Data;
using System.Collections.Generic;
using System.IO;

Etapa 1 – Abrir o Arquivo

O primeiro passo é criar uma instância Parser que aponte para o arquivo compactado. GetContainer() devolve uma coleção de objetos ContainerItem – um por entrada dentro do arquivo.

// Path to the archive you want to scan
string archivePath = "./SampleDocs/InvoicesArchive.zip";

using (Parser parser = new Parser(archivePath))
{
    // Retrieve every file (or nested archive) inside the container
    IEnumerable<ContainerItem> attachments = parser.GetContainer();

    if (attachments == null)
    {
        Console.WriteLine("Archive is empty or could not be read.");
        return;
    }

    // Hand off the collection to a helper that extracts text/metadata
    ExtractDataFromAttachments(attachments);
}

O que está acontecendo:

  • O construtor Parser carrega o arquivo sem extraí‑lo para o disco.
  • GetContainer() lê de forma preguiçosa o diretório do arquivo compactado e fornece objetos ContainerItem com os quais você pode trabalhar.

Etapa 2 – Processar Cada Entrada

ExtractDataFromAttachments percorre a lista ContainerItem, imprime metadados básicos, detecta arquivos compactados aninhados e extrai texto de documentos normais. O método é totalmente reutilizável – chame‑o uma vez para um arquivo de nível superior e novamente para qualquer arquivo aninhado que você descobrir.

/// <summary>
/// Recursively extracts metadata and plain‑text from each item in an archive.
/// </summary>
static void ExtractDataFromAttachments(IEnumerable<ContainerItem> attachments)
{
    foreach (ContainerItem item in attachments)
    {
        // Print a quick line with file name and size (optional)
        Console.WriteLine($"File: {item.FilePath} | Size: {item.Metadata.Size} bytes");

        try
        {
            // Each ContainerItem can open its own Parser instance
            using (Parser itemParser = item.OpenParser())
            {
                if (itemParser == null)
                {
                    // The item is not a supported document – skip it
                    continue;
                }

                // Detect nested archives by extension (case‑insensitive)
                bool isArchive = item.FilePath.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) ||
                                 item.FilePath.EndsWith(".rar", StringComparison.OrdinalIgnoreCase);

                if (isArchive)
                {
                    // Recursively process the inner archive
                    IEnumerable<ContainerItem>? nested = itemParser.GetContainer();
                    if (nested != null)
                    {
                        ExtractDataFromAttachments(nested);
                    }
                }
                else
                {
                    // Regular document – extract its raw text
                    using (TextReader reader = itemParser.GetText())
                    {
                        string text = reader.ReadToEnd();
                        Console.WriteLine($"Extracted {text.Length} characters from {item.FilePath}");
                        // Here you could store `text` in a database, index it, etc.
                    }
                }
            }
        }
        catch (UnsupportedDocumentFormatException)
        {
            // The file type is not supported by GroupDocs.Parser – ignore gracefully
            Console.WriteLine($"Skipping unsupported format: {item.FilePath}");
        }
    }
}

Pontos‑chave

  • Acesso a metadadositem.Metadata fornece nome do arquivo, tamanho, data de criação, etc., sem ler o conteúdo do arquivo.
  • Manipulação recursiva – O mesmo método se chama novamente ao encontrar outro ZIP/RAR, proporcionando suporte a aninhamento ilimitado.
  • Resiliência a errosUnsupportedDocumentFormatException é capturado para que um único arquivo problemático não interrompa toda a execução.

Etapa 3 – Juntando Tudo

A seguir, um programa mínimo, pronto para copiar e colar, que combina os dois trechos anteriores. Ele demonstra um fluxo completo de ponta a ponta: instalar, abrir, processar e relatar.

using GroupDocs.Parser;
using GroupDocs.Parser.Data;
using System;
using System.Collections.Generic;
using System.IO;

class ArchiveTextExtractor
{
    static void Main(string[] args)
    {
        string archivePath = args.Length > 0 ? args[0] : "./SampleDocs/InvoicesArchive.zip";
        using (Parser parser = new Parser(archivePath))
        {
            IEnumerable<ContainerItem> attachments = parser.GetContainer();
            if (attachments == null)
            {
                Console.WriteLine("No items found in the archive.");
                return;
            }
            ExtractDataFromAttachments(attachments);
        }
    }

    static void ExtractDataFromAttachments(IEnumerable<ContainerItem> attachments)
    {
        foreach (ContainerItem item in attachments)
        {
            Console.WriteLine($"File: {item.FilePath} | Size: {item.Metadata.Size} bytes");
            try
            {
                using (Parser itemParser = item.OpenParser())
                {
                    if (itemParser == null) continue;

                    bool isArchive = item.FilePath.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) ||
                                     item.FilePath.EndsWith(".rar", StringComparison.OrdinalIgnoreCase);

                    if (isArchive)
                    {
                        var nested = itemParser.GetContainer();
                        if (nested != null) ExtractDataFromAttachments(nested);
                    }
                    else
                    {
                        using (TextReader reader = itemParser.GetText())
                        {
                            string text = reader.ReadToEnd();
                            Console.WriteLine($"Extracted {text.Length} chars from {item.FilePath}");
                        }
                    }
                }
            }
            catch (UnsupportedDocumentFormatException)
            {
                Console.WriteLine($"Unsupported format: {item.FilePath}");
            }
        }
    }
}

Execute o programa informando o caminho para seu arquivo compacto:

dotnet run -- ./Data/LegalDocs.zip

Melhores Práticas e Dicas

  • Limite as opções de análise – Por padrão o Parser extrai todo o conteúdo suportado. Se você precisar apenas de texto, evite chamar métodos pesados adicionais como GetImages().
  • Arquivos grandes – Procese os itens sequencialmente, como demonstrado; evite carregar todos os textos na memória de uma só vez.
  • Desempenho – Pule arquivos compactados aninhados que você não precisa verificando a extensão antes de recursar.
  • Tratamento de erros – Sempre capture UnsupportedDocumentFormatException; muitos arquivos corporativos contêm binários que o parser não consegue ler.

Conclusão

O GroupDocs.Parser para .NET oferece uma forma limpa e em memória de ler cada documento dentro de arquivos ZIP ou RAR, não importa o quão profundamente estejam aninhados. Com apenas algumas linhas de código, você pode substituir pipelines complexos de descompactação + análise, reduzir a sobrecarga de I/O e criar serviços confiáveis de ingestão de documentos.

Próximos passos

Recursos Adicionais