소개

귀사의 비즈니스가 압축된 ZIP 또는 RAR 파일로 제공되는 대량의 청구서, 법률 문서 또는 이메일 내보내기를 수집해야 할 때, 전통적인 방식은 파일을 디스크에 압축 해제하고, 각 파일을 별도의 리더로 열고, 임시 파일을 삭제하는 것입니다. 이러한 왕복 작업은 비용이 많이 드는 I/O를 추가하고 정리를 복잡하게 만들며, 중첩된 아카이브 처리를 악몽처럼 만듭니다.

GroupDocs.Parser for .NET은 이러한 문제점을 해소합니다. 아카이브를 직접 열고, 모든 항목을 열거하며, 원시 텍스트(및 메타데이터)를 완전히 메모리 내에서 추출할 수 있습니다. 이 문서에서는 다음을 배웁니다:

  • Parser NuGet 패키지 설치
  • 단일 패스로 플랫 아카이브에서 텍스트 추출
  • 중첩된 ZIP/RAR 파일을 재귀적으로 탐색
  • 견고한 처리를 위한 모범 설정 적용

인‑메모리 아카이브 파싱이 중요한 이유

아카이브를 메모리에서 처리하면 다음과 같은 이점이 있습니다:

  • 임시 파일 제로 – 디스크에 잔여 파일이 남지 않습니다.
  • 속도 – 각 항목에 대한 추가 읽기/쓰기 사이클을 피합니다.
  • 확장성 – 파일 시스템이 없을 수 있는 대용량 아카이브 또는 클라우드 스트림을 처리할 수 있습니다.

사전 요구 사항

  • .NET 6.0 이상
  • GroupDocs.Parser for .NET (최신 버전) – 무료 평가판을 위해 임시 라이선스를 확인하십시오.
  • 지원되는 문서(PDF, DOCX, TXT 등)를 포함한 ZIP 또는 RAR 아카이브

설치

dotnet add package GroupDocs.Parser

필요한 네임스페이스 추가:

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

1단계 – 아카이브 열기

첫 번째 단계는 아카이브 파일을 가리키는 Parser 인스턴스를 만드는 것입니다. GetContainer()는 아카이브 내부 항목별 ContainerItem 객체 컬렉션을 반환합니다.

// 스캔하려는 아카이브 경로
string archivePath = "./SampleDocs/InvoicesArchive.zip";

using (Parser parser = new Parser(archivePath))
{
    // 컨테이너 내부의 모든 파일(또는 중첩 아카이브) 가져오기
    IEnumerable<ContainerItem> attachments = parser.GetContainer();

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

    // 컬렉션을 텍스트/메타데이터 추출 도우미에 전달
    ExtractDataFromAttachments(attachments);
}

동작 설명:

  • Parser 생성자는 아카이브를 디스크에 추출하지 않고 로드합니다.
  • GetContainer()는 아카이브 디렉터리를 지연 읽기 방식으로 탐색하고 ContainerItem 객체를 제공합니다.

2단계 – 각 항목 처리

ExtractDataFromAttachmentsContainerItem 목록을 순회하면서 기본 메타데이터를 출력하고, 중첩 아카이브를 감지하며, 일반 문서에서 텍스트를 추출합니다. 이 메서드는 완전히 재사용 가능하며, 최상위 아카이브에 한 번 호출하고 발견되는 중첩 아카이브에 다시 호출하면 됩니다.

/// <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)
    {
        // 파일 이름과 크기를 간단히 출력 (선택 사항)
        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}");
        }
    }
}

핵심 포인트

  • 메타데이터 접근item.Metadata를 통해 파일 이름, 크기, 생성 날짜 등을 파일 내용을 읽지 않고 얻을 수 있습니다.
  • 재귀 처리 – ZIP/RAR을 만나면 동일 메서드를 호출해 무한 중첩을 지원합니다.
  • 오류 복원력UnsupportedDocumentFormatException을 잡아 하나의 잘못된 파일이 전체 실행을 중단하지 않게 합니다.

3단계 – 전체 흐름 합치기

아래는 앞의 두 스니펫을 합친 최소 실행 가능한 프로그램 예시입니다. 설치 → 열기 → 처리 → 보고 전체 흐름을 보여줍니다.

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

프로그램을 아카이브 경로와 함께 실행합니다:

dotnet run -- ./Data/LegalDocs.zip

모범 사례 및 팁

  • 파싱 옵션 제한 – 기본적으로 Parser는 모든 지원 콘텐츠를 추출합니다. 텍스트만 필요하면 GetImages()와 같은 무거운 메서드 호출을 피하십시오.
  • 대용량 아카이브 – 예시와 같이 항목을 순차적으로 처리하고, 텍스트를 한 번에 모두 메모리에 로드하지 마세요.
  • 성능 – 재귀 호출 전에 파일 확장자를 확인해 필요 없는 중첩 아카이브는 건너뛰세요.
  • 오류 처리 – 항상 UnsupportedDocumentFormatException을 잡아두세요. 기업용 아카이브에는 파서가 읽을 수 없는 바이너리가 많이 포함될 수 있습니다.

결론

GroupDocs.Parser for .NET은 ZIP 또는 RAR 아카이브 내부의 모든 문서를 깊이 중첩되었든 상관없이 메모리 내에서 깔끔하게 읽을 수 있는 방법을 제공합니다. 몇 줄의 코드만으로 복잡한 압축‑해제‑파싱 파이프라인을 대체하고 I/O 오버헤드를 줄이며 신뢰성 높은 문서 수집 서비스를 구축할 수 있습니다.

다음 단계

  • 문서 비교 또는 메타데이터 추출 기능을 살펴보세요.
  • 동일 API로 아카이브 파일에서 이미지를 추출하는 방법을 배우세요.
  • 추출한 텍스트를 검색 인덱스 또는 AI 파이프라인에 통합하세요.

추가 자료