Introduzione

Quando la tua azienda deve ingerire grandi lotti di fatture, documenti legali o esportazioni di email che arrivano come file compressi ZIP o RAR, l’approccio tradizionale consiste nello decomprimerli su disco, aprire ogni file con un lettore separato e poi scartare i file temporanei. Questo andata‑ritorno aggiunge costosi I/O, complica la pulizia e rende la gestione degli archivi annidati un incubo.

GroupDocs.Parser per .NET elimina questi punti dolenti. Consente di aprire un archivio direttamente, enumerare ogni voce e estrarre testo grezzo (e metadati) interamente in memoria. In questo articolo imparerai a:

  • Installare il pacchetto NuGet Parser.
  • Estrarre testo da un archivio piatto in un unico passaggio.
  • Camminare ricorsivamente attraverso file ZIP/RAR annidati.
  • Applicare impostazioni di best‑practice per una elaborazione robusta.

Perché l’analisi degli archivi in memoria è importante

Elaborare gli archivi in memoria ti offre:

  • Zero file temporanei – nessun ingombro su disco, nessun file residuo.
  • Velocità – evita il ciclo extra di lettura/scrittura per ogni voce.
  • Scalabilità – gestisci archivi di grandi dimensioni o stream basati su cloud dove un file system potrebbe non essere disponibile.

Prerequisiti

  • .NET 6.0 o versioni successive.
  • GroupDocs.Parser per .NET (ultima versione) – vedi la licenza temporanea per una valutazione gratuita.
  • Un archivio ZIP o RAR contenente documenti supportati (PDF, DOCX, TXT, ecc.).

Installazione

dotnet add package GroupDocs.Parser

Aggiungi gli spazi dei nomi richiesti:

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

Passo 1 – Aprire l’archivio

Il primo passo è creare un’istanza Parser che punti al file archivio. GetContainer() restituisce una raccolta di oggetti ContainerItem – uno per ogni voce all’interno dell’archivio.

// 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);
}

Cosa sta succedendo:

  • Il costruttore Parser carica l’archivio senza estrarlo su disco.
  • GetContainer() legge pigramente la directory dell’archivio e ti fornisce oggetti ContainerItem con cui lavorare.

Passo 2 – Elaborare ogni voce

ExtractDataFromAttachments attraversa l’elenco ContainerItem, stampa i metadati di base, rileva gli archivi annidati ed estrae il testo dai documenti regolari. Il metodo è completamente riutilizzabile – chiamalo una volta per un archivio di primo livello e di nuovo per qualsiasi archivio annidato che scopri.

/// <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}");
        }
    }
}

Punti chiave

  • Accesso ai metadatiitem.Metadata fornisce nome file, dimensione, data di creazione, ecc., senza leggere il contenuto del file.
  • Gestione ricorsiva – Lo stesso metodo si richiama quando incontra un altro ZIP/RAR, garantendo supporto a annidamenti illimitati.
  • Resilienza agli errori – L’eccezione UnsupportedDocumentFormatException viene catturata così un singolo file difettoso non interrompe l’intera esecuzione.

Passo 3 – Mettere tutto insieme

Di seguito trovi un programma minimale, pronto per il copia‑incolla, che combina gli snippet precedenti. Dimostra un flusso completo end‑to‑end: installazione, apertura, elaborazione e report.

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}");
            }
        }
    }
}

Esegui il programma passando il percorso del tuo archivio:

dotnet run -- ./Data/LegalDocs.zip

Best practice e consigli

  • Limita le opzioni di parsing – Per impostazione predefinita il Parser estrae tutti i contenuti supportati. Se ti serve solo il testo, evita di chiamare metodi pesanti aggiuntivi come GetImages().
  • Archivi di grandi dimensioni – Elabora gli elementi sequenzialmente come mostrato; evita di caricare tutti i testi in memoria in una volta.
  • Performance – Salta gli archivi annidati di cui non hai bisogno controllando l’estensione del file prima di ricorsare.
  • Gestione degli errori – Cattura sempre UnsupportedDocumentFormatException; molti archivi aziendali contengono binari che il parser non può leggere.

Conclusione

GroupDocs.Parser per .NET offre un modo pulito e in‑memoria per leggere ogni documento all’interno di archivi ZIP o RAR, indipendentemente da quanto siano annidati. Con poche righe di codice puoi sostituire pipeline complesse di unzip‑plus‑parse, ridurre l’overhead I/O e costruire servizi affidabili di ingestione documenti.

Passaggi successivi

  • Esplora le funzionalità di confronto documenti o di estrazione dei metadati.
  • Scopri come estrarre immagini da file archiviati con la stessa API.
  • Integra il testo estratto in un indice di ricerca o in una pipeline AI.

Risorse aggiuntive