使用SharpCompress提取7-Zip归档子目录报错问题求助
异常原因及解决方案
异常原因
- 路径处理逻辑有误:直接使用
Replace替换路径可能意外修改文件名中的匹配字符串,导致路径混乱,进而尝试操作无效条目。 - 未限定目标子目录范围:代码遍历了归档中所有非目录条目,包含了不属于目标子目录的内容,其中部分条目可能没有有效数据流(比如归档内部元数据),触发
System.InvalidOperationException: 'File does not have a stream.'异常。
正确提取子目录的实现方法
修正路径处理逻辑,精准筛选目标子目录下的可提取条目,代码如下:
using SharpCompress.Archives; using SharpCompress.Archives.SevenZip; using SharpCompress.Common; using System.IO; using System.Linq; string srcFile = "Put the path to your *.7z file here"; string subPath = "Put the sub-path inside the archive you want to extract here"; // 确保子目录路径以目录分隔符结尾,避免误匹配文件名前缀 if (!subPath.EndsWith(Path.DirectorySeparatorChar.ToString())) { subPath += Path.DirectorySeparatorChar; } string dstPath = "Put the path to want to extract to here"; using (SevenZipArchive archive = SevenZipArchive.Open(srcFile)) { Console.Write($"Extracting {srcFile}... "); // 筛选目标子目录下的可提取文件条目 var targetEntries = archive.Entries .Where(entry => !entry.IsDirectory && entry.IsExtractable && entry.Key.StartsWith(subPath)); foreach (SevenZipArchiveEntry entry in targetEntries) { // 构建目标路径:截取子目录后的相对路径,拼接至目标目录 string relativePath = entry.Key.Substring(subPath.Length); string fileName = Path.Combine(dstPath, relativePath); Console.WriteLine($" FROM: {entry.Key}"); Console.WriteLine($" TO: {fileName}"); // 创建文件父目录 Directory.CreateDirectory(Path.GetDirectoryName(fileName)); entry.WriteToFile(fileName, new ExtractionOptions() { Overwrite = true }); } Console.WriteLine("DONE!"); } Console.Write($"{Environment.NewLine}Press any key to continue..."); Console.ReadKey();
关键优化点
- 精准筛选条目:通过
entry.Key.StartsWith(subPath)确保只处理目标子目录下的内容,同时用entry.IsExtractable跳过无效条目。 - 可靠路径构建:用
Substring截取相对路径,配合Path.Combine拼接目标路径,避免Replace带来的意外替换问题。 - 避免误匹配:给
subPath添加结尾的目录分隔符,防止匹配到文件名前缀与子目录名一致的条目。
内容的提问来源于stack exchange,提问作者Xorcist
相关产品推荐
相关产品推荐

