Giới thiệu

Khi doanh nghiệp của bạn cần nhập hàng loạt hoá đơn, tài liệu pháp lý hoặc xuất khẩu email dưới dạng các tệp nén ZIP hoặc RAR, cách tiếp cận truyền thống là giải nén chúng ra đĩa, mở từng tệp bằng một trình đọc riêng và sau đó xóa các tệp tạm thời. Quá trình này tạo ra vòng quay I/O tốn kém, phức tạp trong việc dọn dẹp và khiến việc xử lý các kho lưu trữ lồng nhau trở nên ác mộng.

GroupDocs.Parser for .NET loại bỏ những điểm đau đớn này. Nó cho phép bạn mở một kho lưu trữ trực tiếp, liệt kê mọi mục, và trích xuất văn bản thô (và siêu dữ liệu) hoàn toàn trong bộ nhớ. Trong bài viết này bạn sẽ học cách:

  • Cài đặt gói NuGet Parser.
  • Lấy văn bản từ một kho lưu trữ phẳng trong một lần duyệt.
  • Đệ quy duyệt qua các tệp ZIP/RAR lồng nhau.
  • Áp dụng các cài đặt thực tiễn tốt nhất để xử lý mạnh mẽ.

Tại sao việc phân tích lưu trữ trong bộ nhớ quan trọng

Xử lý các kho lưu trữ trong bộ nhớ mang lại cho bạn:

  • Không có tệp tạm thời – không gây lộn xộn đĩa, không có tệp còn lại.
  • Tốc độ – tránh vòng đọc/ghi thêm cho mỗi mục.
  • Khả năng mở rộng – xử lý các kho lưu trữ lớn hoặc các luồng dựa trên đám mây nơi hệ thống tệp có thể không khả dụng.

Yêu cầu trước

  • .NET 6.0 hoặc mới hơn.
  • GroupDocs.Parser for .NET (phiên bản mới nhất) – xem giấy phép tạm thời để dùng thử miễn phí.
  • Một kho lưu trữ ZIP hoặc RAR chứa các tài liệu được hỗ trợ (PDF, DOCX, TXT, v.v.).

Cài đặt

dotnet add package GroupDocs.Parser

Thêm các namespace cần thiết:

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

Bước 1 – Mở lưu trữ

Bước đầu tiên là tạo một thể hiện Parser trỏ tới tệp kho lưu trữ. GetContainer() trả về một tập hợp các đối tượng ContainerItem – một đối tượng cho mỗi mục bên trong kho lưu trữ.

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

What’s happening:

  • Trình khởi tạo Parser tải kho lưu trữ không giải nén ra đĩa.
  • GetContainer() đọc một cách lười danh sách thư mục của kho lưu trữ và cung cấp cho bạn các đối tượng ContainerItem có thể thao tác.

Bước 2 – Xử lý mỗi mục

ExtractDataFromAttachments duyệt danh sách ContainerItem, in siêu dữ liệu cơ bản, phát hiện các kho lưu trữ lồng nhau, và trích xuất văn bản từ các tài liệu thường. Phương thức này hoàn toàn có thể tái sử dụng – gọi một lần cho kho lưu trữ cấp trên và lại một lần cho bất kỳ kho lưu trữ lồng nào bạn phát hiện.

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

Những điểm chính

  • Truy cập siêu dữ liệuitem.Metadata cung cấp cho bạn tên tệp, kích thước, ngày tạo, v.v., mà không cần đọc nội dung tệp.
  • Xử lý đệ quy – Phương thức tự gọi lại khi gặp một ZIP/RAR khác, cho phép hỗ trợ vô hạn mức lồng nhau.
  • Khả năng chịu lỗiUnsupportedDocumentFormatException được bắt lại để một tệp hỏng đơn lẻ không làm dừng toàn bộ quá trình.

Bước 3 – Kết hợp mọi thứ lại

Dưới đây là một chương trình tối thiểu, có thể sao chép và dán, kết hợp hai đoạn mã ở trên. Nó minh họa một luồng công việc hoàn chỉnh từ cài đặt, mở, xử lý tới báo cáo.

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

Chạy chương trình với đường dẫn tới kho lưu trữ của bạn:

dotnet run -- ./Data/LegalDocs.zip

Thực hành tốt nhất & Mẹo

  • Giới hạn tùy chọn phân tích – Mặc định Parser sẽ trích xuất mọi nội dung được hỗ trợ. Nếu bạn chỉ cần văn bản, tránh gọi các phương thức nặng như GetImages().
  • Kho lưu trữ lớn – Xử lý các mục theo thứ tự như trên; tránh tải toàn bộ văn bản vào bộ nhớ cùng lúc.
  • Hiệu suất – Bỏ qua các kho lưu trữ lồng mà bạn không cần bằng cách kiểm tra phần mở rộng tệp trước khi đệ quy.
  • Xử lý lỗi – Luôn bắt UnsupportedDocumentFormatException; nhiều kho lưu trữ doanh nghiệp chứa các tệp nhị phân mà trình phân tích không thể đọc.

Kết luận

GroupDocs.Parser for .NET cung cấp một cách sạch sẽ, trong bộ nhớ để đọc mọi tài liệu bên trong các kho lưu trữ ZIP hoặc RAR, bất kể chúng được lồng bao nhiêu mức. Chỉ với vài dòng mã, bạn có thể thay thế các quy trình phức tạp “giải nén + phân tích”, giảm chi phí I/O và xây dựng các dịch vụ nhập tài liệu đáng tin cậy.

Next steps

  • Khám phá các tính năng so sánh tài liệu hoặc trích xuất siêu dữ liệu.
  • Tìm hiểu cách trích xuất hình ảnh từ các tệp được lưu trữ bằng cùng API.
  • Tích hợp văn bản đã trích xuất vào chỉ mục tìm kiếm hoặc quy trình AI.

Tài nguyên bổ sung