C# 操作光盘文件系统(ISO 9660) C#如何直接读取光盘镜像中的文件目录

来源:这里教程网 时间:2026-02-21 17:42:07 作者:

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
会直接 throw
InvalidDataException
示例代码片段:
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
释放,否则后续操作会 throw
ObjectDisposedException

ISO 文件系统解析本身不慢,但首次构造

Iso9660FileSystem
对超大镜像(如 DVD-9)仍可能耗几百毫秒,这部分延迟没法绕开——毕竟得从开头找到卷描述符,再跳转到目录区位置。

相关推荐