Introduction

Lorsque votre entreprise doit ingérer de gros lots de factures, de documents juridiques ou d’exportations d’e‑mails qui arrivent sous forme de fichiers ZIP ou RAR compressés, l’approche traditionnelle consiste à les décompresser sur le disque, à ouvrir chaque fichier avec un lecteur distinct, puis à supprimer les fichiers temporaires. Ce aller‑retour ajoute des I/O coûteux, complique le nettoyage et rend la gestion des archives imbriquées un cauchemar.

GroupDocs.Parser for .NET élimine ces points douloureux. Il vous permet d’ouvrir une archive directement, d’énumérer chaque entrée et d’extraire le texte brut (et les métadonnées) entièrement en mémoire. Dans cet article, vous apprendrez comment :

  • Installer le package NuGet Parser.
  • Extraire le texte d’une archive plate en un seul passage.
  • Parcourir récursivement les fichiers ZIP/RAR imbriqués.
  • Appliquer des paramètres de bonnes pratiques pour un traitement robuste.

Pourquoi l’analyse d’archives en mémoire est importante

Le traitement des archives en mémoire vous offre :

  • Aucun fichier temporaire – aucune accumulation sur le disque, aucun fichier résiduel.
  • Rapidité – évite le cycle de lecture/écriture supplémentaire pour chaque entrée.
  • Scalabilité – gère de grandes archives ou des flux cloud où le système de fichiers peut ne pas être disponible.

Prérequis

  • .NET 6.0 ou version ultérieure.
  • GroupDocs.Parser for .NET (dernière version) – voir la licence temporaire pour une évaluation gratuite.
  • Une archive ZIP ou RAR contenant des documents pris en charge (PDF, DOCX, TXT, etc.).

Installation

dotnet add package GroupDocs.Parser

Ajoutez les espaces de noms requis :

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

Étape 1 – Ouvrir l’archive

La première étape consiste à créer une instance Parser qui pointe vers le fichier d’archive. GetContainer() renvoie une collection d’objets ContainerItem – un par entrée dans l’archive.

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

Ce qui se passe :

  • Le constructeur Parser charge l’archive sans l’extraire sur le disque.
  • GetContainer() lit paresseusement le répertoire de l’archive et vous fournit des objets ContainerItem avec lesquels travailler.

Étape 2 – Traiter chaque entrée

ExtractDataFromAttachments parcourt la liste ContainerItem, affiche des métadonnées de base, détecte les archives imbriquées et extrait le texte des documents ordinaires. La méthode est entièrement réutilisable – appelez‑la une fois pour une archive de niveau supérieur et à nouveau pour chaque archive imbriquée que vous découvrez.

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

Points clés

  • Accès aux métadonnéesitem.Metadata vous fournit le nom du fichier, la taille, la date de création, etc., sans lire le contenu du fichier.
  • Gestion récursive – La même méthode s’appelle elle‑même lorsqu’elle rencontre un autre ZIP/RAR, vous offrant un support d’imbrication illimité.
  • Résilience aux erreursUnsupportedDocumentFormatException est interceptée afin qu’un seul fichier défectueux n’interrompe pas l’ensemble du processus.

Étape 3 – Mettre le tout ensemble

Voici un programme minimal, copiable‑collable, qui combine les deux extraits précédents. Il montre un flux complet de bout en bout : installation, ouverture, traitement et rapport.

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

Exécutez le programme en indiquant le chemin de votre archive :

dotnet run -- ./Data/LegalDocs.zip

Bonnes pratiques & astuces

  • Limitez les options d’analyse – Par défaut, Parser extrait tout le contenu pris en charge. Si vous avez seulement besoin du texte, évitez d’appeler des méthodes lourdes supplémentaires comme GetImages().
  • Grandes archives – Traitez les éléments séquentiellement comme montré ; évitez de charger tous les textes en mémoire d’un coup.
  • Performance – Ignorez les archives imbriquées dont vous n’avez pas besoin en vérifiant l’extension du fichier avant de récursiver.
  • Gestion des erreurs – Capturez toujours UnsupportedDocumentFormatException ; de nombreuses archives d’entreprise contiennent des binaires que le parseur ne peut pas lire.

Conclusion

GroupDocs.Parser for .NET offre une méthode propre, en mémoire, pour lire chaque document à l’intérieur d’archives ZIP ou RAR, quel que soit le niveau d’imbrication. En quelques lignes de code, vous pouvez remplacer des pipelines complexes « dézipper + parser », réduire la surcharge I/O et créer des services d’ingestion de documents fiables.

Prochaines étapes

Ressources supplémentaires