不能用 system.io 直接读 iso 文件,因为 iso 9660 是文件系统格式而非归档格式,.net 基础 i/o 不支持其 lba 映射和目录结构;应使用 discutils.iso9660 库解析。

用 System.IO 直接读 ISO 文件?不行,会报错
ISO 9660 是文件系统格式,不是普通压缩包。直接对 .iso 文件调用 Directory.GetFiles 或 new DirectoryInfo() 会抛出 IOException:“找不到文件的一部分”,因为 .NET 基础 I/O 不理解 ISO 9660 的目录结构和 LBA 映射逻辑。
常见错误现象:把 ISO 当成 ZIP 用 ZipArchive 打开 → 报 InvalidDataException;或用 FileStream + StreamReader 乱读 → 得到一堆不可读字节。
- ISO 不是归档格式(如 ZIP/RAR),它是一块“虚拟磁盘”的原始镜像,含引导区、卷描述符、路径表、目录记录等
-
System.IO只支持 FAT/NTFS/exFAT 等挂载后的卷,不解析光盘文件系统元数据 - Windows 虽能双击挂载 ISO,但那是 shell 和
cdrom.sys在背后做的,.NET 层无感知
推荐方案:用 DiscUtils 库解析 ISO 9660
DiscUtils 是目前最稳定、文档最清晰的纯 C# ISO 9660 解析库(MIT 开源,NuGet 包名:DiscUtils.Iso9660)。它不依赖 Windows API 或外部工具,所有解析都在托管代码中完成。
使用场景:离线读取 ISO 内容、提取特定文件、遍历目录树、获取文件时间戳或隐藏属性。
- 安装命令:
dotnet add package DiscUtils.Iso9660 - 核心类是
Iso9660FileSystem,构造时传入Stream(必须可 seek,不能是NetworkStream) - 注意:ISO 文件必须完整且未损坏,部分刻录中途失败的镜像可能缺少主卷描述符,
Iso9660FileSystem会直接 throwInvalidDataException - 示例代码片段:
using DiscUtils.Iso9660;
using var isoStream = File.OpenRead("game.iso");
using var fs = new Iso9660FileSystem(isoStream);
foreach (var file in fs.GetFiles("/")) {
Console.WriteLine(file); // 输出类似 "/README.TXT"
}路径写法和大小写敏感性容易踩坑
ISO 9660 Level 1 规范强制文件名 8.3 格式、全大写、无 Unicode。虽然 Level 2/3 和 Joliet 扩展支持长名和小写,但 DiscUtils 默认按 Joliet 优先(如果存在),否则回落到 Rock Ridge 或标准 ISO。
这意味着你看到的路径可能是 /Documents/Report.pdf(Joliet),也可能是 /DOCUMENTS/REPORT.PDF(Level 1),甚至带 Rock Ridge 扩展的 /documents/report.pdf(小写+长名)——取决于原始镜像如何生成。
- 不要硬编码路径大小写,用
fs.GetDirectories(path)和fs.GetFiles(path)枚举后匹配,而不是直接fs.OpenFile("/DATA/FILE.TXT") - 路径分隔符始终用正斜杠
/,即使在 Windows 上;反斜杠\会导致ArgumentException - 根路径必须写成
"/",不是""或"./",否则GetFiles返回空
性能与内存:大 ISO 镜像别一次性加载
DiscUtils.Iso9660FileSystem 构造时会解析整个 ISO 的目录结构(PVD、path table、directory records),但不会把所有文件内容读进内存。不过,如果 ISO 超过 4GB,且你的进程是 x86,可能因地址空间不足而触发 OutOfMemoryException(尤其在 32 位调试模式下)。
- 确保项目目标平台设为
x64(右键项目 → 属性 → 生成 → 平台目标) - 避免反复 new
Iso9660FileSystem—— 它内部缓存了关键元数据,复用实例更高效 - 如果只查某几个文件,不用遍历全盘,直接用
fs.GetFileEntry("/path/to/file")拿元数据,再按需OpenFile流式读取 - 流必须保持打开状态直到
Iso9660FileSystem释放,否则后续操作会 throwObjectDisposedException
ISO 文件系统解析本身不慢,但首次构造 Iso9660FileSystem 对超大镜像(如 DVD-9)仍可能耗几百毫秒,这部分延迟没法绕开——毕竟得从开头找到卷描述符,再跳转到目录区位置。








