使用纯 Swift API 读取/写入 ISO9660 (CD, DVD) 镜像。 它支持的最新规范是 ECMA-119 第四版,2019年6月。
光盘媒体使用 ISO 9660 格式来存储其内容,以及相关的辅助标准,如 Joliet 扩展、 系统使用共享协议 和 Rock Ridge。
此库提供了一个纯 Swift API,它在用户空间中运行,可以直接访问和操作 ISO 镜像,而无需挂载这些镜像。
import Foundation
import ISO9660
// create media
let media = try! ISOImageFileMedia("cdimage.iso")
// create a filesystem object using this media
let fs = try! ISOFileSystem(media)
// access root directory and list its children
let dir = try! fs.getFSEntry("/")
for child in try fs.list(directory: directory) {
print(child.name)
}
// get input stream to a file
let file = try! fs.getFSEntry("/some/file/of/mine")
let inputStream = try! fs.readFile(file)
defer {
inputStream.close()
}
while inputStream.hasBytesAvailable {
// do something
}
import Foundation
import ISO9660
let folderRoot = "path/to/data"
// create media
let media = try! ISOImageFileMedia("cdimage.iso", readonly: false)
// prepare write options
let writeOptions = ISOWriter.WriteOptions(volumeIdentifier: "MYDATA")
// prepare writer - the last parameter is a closure that returns an `InputStream`
// to the file referenced by `path`
let writer = ISOWriter(media: media, options: writeOptions) { path in
let localPath = "\(folderRoot)\(path)"
return InputStream(fileAtPath: localPath)!
}
// add a file
let volPath = "/boot/grub.cfg"
let localPath = "\(folderRoot)\(volPath)"
let fileSize = try! FileManager.default.attributesOfItem(atPath: localPath)[.size] as! UInt64
try! writer.addFile(path: volPath, size: fileSize, metadata: nil)
// write
try! writer.writeAndClose()
ISO 9660 规范的技术细节在 ECMA-119 中指定。 对于通常的读取/写入操作来说,这并非必需,但本节对于那些试图了解底层机制的人来说可能很有用。
在较高层次上,需要理解以下重要概念:
物理存储:ISO 9660 镜像可以存在于光盘媒体(如 CD/DVD 等)中,但现在主要以 .iso
文件的形式分发。 更多细节可以在 ISOImageMedia
中找到,它作为物理媒体的抽象层。 ISOImageFileMedia
是 .iso
文件的具体实现。
逻辑块:ISO 9660 文件系统使用 LBA(逻辑块寻址)方案,即地址(例如,文件的位置)以逻辑块号表示。 因此,如果文件的起始地址为 1000
,则表示字节地址为 1000 * 2048
字节(假设块大小为 2048 字节),而不是 1000
。 块大小在卷描述符中定义。
卷描述符:这些描述了卷的顶层信息,并显示为前 16 个扇区之后的一系列描述符。 有关不同类型的描述符,请参见 VolumeDescriptor
。 最重要的是 VolumeDescriptor/primary
、VolumeDescriptor/supplementary
和 VolumeDescriptor/enhanced
类型,因为它们通过 VolumeDirectoryDescriptor
描述存储在卷内的目录结构。
目录树:目录树通过两个不同的结构表示:
DirectoryRecord
结构来描述自身。 从 VolumeDirectoryDescriptor/rootDirectory
开始,可以遍历路径树,跳转到不同的 DirectoryRecord
以到达我们需要的文件/目录。PathTableRecord
。文件/目录元数据:有关文件的额外元数据(例如,长名称、权限、uid/gid 等)可以通过两种不同的方式获得:
ExternalAttributeRecord
。DirectoryRecord
的 DirectoryRecord/systemUse
字段被重新用于存储元数据。 每个元数据字段都通过 SUSPEntry
记录存储,这些记录的集合构成一个 SUSPArea
。ISO9660 在 MIT 许可证下发布。 有关详细信息,请参见 LICENSE。
除非您明确声明,否则您有意提交的任何贡献,都应按照上述许可进行许可。 您还声明该贡献全部或部分由您创建,并且您有权根据上述许可提交该作品。