Introduction
当您的业务需要批量处理大量发票、法律文件或以压缩 ZIP 或 RAR 文件形式导出的邮件时,传统做法是先将它们解压到磁盘,使用单独的读取器逐个打开文件,然后删除临时文件。这种往返会产生大量 I/O 开销,增加清理难度,并且处理嵌套压缩包时会非常棘手。
GroupDocs.Parser for .NET 消除了这些痛点。它可以 直接打开压缩包,枚举其中的每个条目,并 在内存中完整提取原始文本(以及元数据)。本文将教您如何:
- 安装 Parser NuGet 包。
- 在单次遍历中从普通压缩包中提取文本。
- 递归遍历嵌套的 ZIP/RAR 文件。
- 应用最佳实践设置以实现稳健的处理。
Why In‑Memory Archive Parsing Matters
在内存中处理压缩包能够为您带来:
- 零临时文件——无需磁盘杂乱,也不会留下残余文件。
- 速度——避免对每个条目进行额外的读/写循环。
- 可扩展性——能够处理大型压缩包或云端流式数据,即使没有文件系统也能工作。
Prerequisites
- .NET 6.0 或更高版本。
- GroupDocs.Parser for .NET(最新版本)——参见 temporary license 获取免费评估。
- 包含受支持文档(PDF、DOCX、TXT 等)的 ZIP 或 RAR 压缩包。
Installation
dotnet add package GroupDocs.Parser
添加所需的命名空间:
using GroupDocs.Parser;
using GroupDocs.Parser.Data;
using System.Collections.Generic;
using System.IO;
Step 1 – Open the Archive
第一步是创建指向压缩包文件的 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);
}
What’s happening:
Parser构造函数在 不解压到磁盘 的情况下加载压缩包。GetContainer()懒惰读取压缩包目录,并提供可供操作的ContainerItem对象。
Step 2 – Process Each Entry
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}");
}
}
}
Key Points
- Metadata access –
item.Metadata给出文件名、大小、创建日期等信息,且无需读取文件内容。 - Recursive handling – 当遇到另一个 ZIP/RAR 时,方法会自行调用自身,支持任意层级的嵌套。
- Error resilience – 捕获
UnsupportedDocumentFormatException,可防止单个错误文件导致整个任务中止。
Step 3 – Putting It All Together
下面是一段最小可运行、可直接复制的完整程序,结合了前面的两个代码片段。它演示了完整的端到端流程:安装、打开、处理并报告。
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
Best Practices & Tips
- Limit parsing options – 默认情况下 Parser 会提取所有受支持的内容。如果只需要文本,请避免调用
GetImages()等额外的重方法。 - Large archives – 如示例所示逐个处理条目,避免一次性将所有文本加载到内存。
- Performance – 在递归之前通过检查文件扩展名来跳过不需要的嵌套压缩包。
- Error handling – 始终捕获
UnsupportedDocumentFormatException,因为企业压缩包中常会出现解析器无法识别的二进制文件。
Conclusion
GroupDocs.Parser for .NET 提供了一种干净的、基于内存的方式读取 ZIP 或 RAR 压缩包中的每个文档,无论其嵌套深度如何。只需几行代码,就可以取代繁琐的“解压‑再‑解析”流程,降低 I/O 开销,并构建可靠的文档摄取服务。
Next steps
- 探索 document comparison 或 metadata extraction 功能。
- 学习使用相同 API 从压缩文件中提取图像。
- 将提取的文本集成到搜索索引或 AI 流程中。