介紹
當您的業務需要處理大量以 ZIP 或 RAR 壓縮檔形式傳送的發票、法律文件或電子郵件匯出檔時,傳統的做法是先將壓縮檔解壓至磁碟,然後使用單獨的讀取器打開每個檔案,最後再刪除暫存檔。這樣的往返會產生昂貴的 I/O、使清理工作變得複雜,且處理巢狀壓縮檔更是噩夢。
GroupDocs.Parser for .NET 消除這些痛點。它讓您 直接開啟壓縮檔、列舉每個條目,並 在記憶體中完整提取純文字(及中繼資料)。在本文中,您將學會:
- 安裝 Parser NuGet 套件。
- 在一次遍歷中從平面壓縮檔取得文字。
- 遞迴遍歷巢狀 ZIP/RAR 檔案。
- 套用最佳實務設定以取得穩定的處理效能。
為何記憶體內部的壓縮檔解析很重要
在記憶體中處理壓縮檔可為您帶來:
- 零暫存檔——不會留下磁碟雜訊,也不會有遺留檔案。
- 速度——避免對每個條目進行額外的讀寫循環。
- 可擴充性——能處理大型壓縮檔或雲端串流,即使檔案系統不可用。
前置條件
- .NET 6.0 或更新版本。
- GroupDocs.Parser for .NET(最新版本)——參見 temporary license 以取得免費評估版。
- 包含支援文件(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 物件集合——每個條目對應一個物件。
// 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);
}
發生了什麼:
Parser建構子在 不將壓縮檔解壓至磁碟 的情況下載入檔案。GetContainer()懶惰地讀取壓縮檔目錄,並提供可供操作的ContainerItem物件。
步驟 2 – 處理每個條目
ExtractDataFromAttachments 會遍歷 ContainerItem 清單、列印基本中繼資料、偵測巢狀壓縮檔,並從普通文件中提取文字。此方法完全可重複使用——對頂層壓縮檔呼叫一次,對發現的任何巢狀壓縮檔再呼叫一次。
/// <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}");
}
}
}
重點說明
- 中繼資料存取——
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 開銷,並打造可靠的文件匯入服務。
後續步驟
- 探索 document comparison 或 metadata extraction 功能。
- 瞭解如何使用相同 API 從壓縮檔中提取影像。
- 將提取的文字整合至搜尋索引或 AI 流程中。