我正在使用 SharpCompress 提取大量包含嵌套档案的档案。我需要能够获取基础存档中每个文件的 CRC,以及基础存档内嵌套存档中每个文件的 CRC。出于性能原因,我需要在 zip 位于内存(例如流)中时执行此操作。(即不要先将它们提取到磁盘,然后再处理它们。)
“RootZip.zip”的示例 Zip 结构
RootZip.zip
RootZip.zip\SubFolderInZip\NestedZipLvl1.rar
RootZip.zip\SubFolderInZip\NestedZipLvl1.rar\SomeOtherSubFolder\NestedZipLvl2.7z
除了嵌套档案之外,每个档案还包含文件。
我需要能够:
- 获取“RootZip.zip”、“SubZipLvl1.zip”和“SubZipLvl2.7z”中每个文件的 CRC。
- 从每个 zip 中提取特定文件(“RootZip.zip”、“SubZipLvl1.zip”和“SubZipLvl2.7z”)
我试过的:
我发现通过 ArchiveFactory 处理每个 zip 并使用 IArchive 接口,我可以使用“archive.Entries[i].crc”获取根 zip 中文件的所有 CRC,但它不允许我使用此方法打开嵌套档案的条目的条目流,以便我也可以获得其中文件的 CRC(参见下面的代码):
private static HashSet<Zip> GetZipInfo(IArchive archive)
{
HashSet<Zip> result = new HashSet<Zip>();
HashSet<long> allCrc = new HashSet<long>();
foreach (var entry in archive.Entries)
{
if (!entry.IsDirectory
&& PathLoc.HasRootFolder(entry.Key))
{
allCrc.Add(entry.Crc);
//TODO: Extract File.
}
else if (!entry.IsDirectory
&& PathLoc.IsZip(entry.Key))
{
// If the entry is a subZip, then start extracting that zip
using (IArchive newArchive = ArchiveFactory.Open(entry.OpenEntryStream()))
{
result.Union(GetZipInfo(archive));
}
}
}
return result;
}
上面的代码抛出了一个异常“$exception {“Stream should be readable and seekable”}”,你会认为这是有道理的,因为我试图在一个已经打开的阅读器中打开一个阅读器......但是......
如果我使用这种使用流的嵌套读取器的方法,我能够提取嵌套档案的内容(删除了错误处理以减小其大小):
private ZipInfo RecursiveParseExample(Stream stream)
{
using (var reader = ReaderFactory.Open(stream))
{
while (reader.MoveToNextEntry())
{
if (!reader.Entry.IsDirectory)
{
if (IsZip(reader.Entry))
{
RecursiveParseExample(reader.OpenEntryStream());
}
else
{
reader.WriteEntryTo(myPath);
}
}
}
}
}
我可以提取嵌套档案,但我找不到从阅读器类的每个文件中获取 CRC 的方法。
如何从嵌套 zip 中的文件中获取 CRC,而无需先将它们提取到磁盘?