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
Parsercarrega o arquivo sem extraí‑lo para o disco. GetContainer()lê de forma preguiçosa o diretório do arquivo compactado e fornece objetosContainerItemcom 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 metadados –
item.Metadatafornece 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 erros –
UnsupportedDocumentFormatExceptioné 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
- Explore os recursos de comparação de documentos ou extração de metadados.
- Aprenda a extrair imagens de arquivos compactados usando a mesma API.
- Integre o texto extraído a um índice de busca ou pipeline de IA.