golang读写ISO9660磁盘镜像文件插件库iso9660的使用
golang读写ISO9660磁盘镜像文件插件库iso9660的使用
简介
iso9660 是一个用于读取和创建ISO9660格式磁盘镜像的Go语言库。需要注意的是,该库不支持Joliet扩展,但正在实验性地支持读取Rock Ridge扩展。如果遇到问题,可以使用v0.3版本,它会忽略Rock Ridge扩展。
基本使用示例
提取ISO镜像内容
package main
import (
"log"
"os"
"github.com/kdomanski/iso9660/util"
)
func main() {
f, err := os.Open("/home/user/myImage.iso")
if err != nil {
log.Fatalf("failed to open file: %s", err)
}
defer f.Close()
if err = util.ExtractImageToDirectory(f, "/home/user/target_dir"); err != nil {
log.Fatalf("failed to extract image: %s", err)
}
}
创建ISO镜像
package main
import (
"log"
"os"
"github.com/kdomanski/iso9660"
)
func main() {
writer, err := iso9660.NewWriter()
if err != nil {
log.Fatalf("failed to create writer: %s", err)
}
defer writer.Cleanup()
f, err := os.Open("/home/user/myFile.txt")
if err != nil {
log.Fatalf("failed to open file: %s", err)
}
defer f.Close()
err = writer.AddFile(f, "folder/MYFILE.TXT")
if err != nil {
log.Fatalf("failed to add file: %s", err)
}
outputFile, err := os.OpenFile("/home/user/output.iso", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err != nil {
log.Fatalf("failed to create file: %s", err)
}
err = writer.WriteTo(outputFile, "testvol")
if err != nil {
log.Fatalf("failed to write ISO image: %s", err)
}
err = outputFile.Close()
if err != nil {
log.Fatalf("failed to close output file: %s", err)
}
}
递归地从目录创建ISO镜像
package main
import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
"github.com/kdomanski/iso9660"
)
func main() {
writer, err := iso9660.NewWriter()
if err != nil {
log.Fatalf("failed to create writer: %s", err)
}
defer writer.Cleanup()
isoFile, err := os.OpenFile("C:/output.iso", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err != nil {
log.Fatalf("failed to create file: %s", err)
}
defer isoFile.Close()
prefix := "F:\\" // 输出ISO文件中要去除的前缀
sourceFolders := []string{"F:\\test1", "F:\\test2"} // 要创建ISO文件的目录
for _, folderName := range sourceFolders {
folderPath := strings.Join([]string{prefix, folderName}, "/")
walk_err := filepath.Walk(folderPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
log.Fatalf("walk: %s", err)
return err
}
if info.IsDir() {
return nil
}
outputPath := strings.TrimPrefix(path, prefix) // 移除源驱动器名称
fmt.Printf("Adding file: %s\n", outputPath)
fileToAdd, err := os.Open(path)
if err != nil {
log.Fatalf("failed to open file: %s", err)
}
defer fileToAdd.Close()
err = writer.AddFile(fileToAdd, outputPath)
if err != nil {
log.Fatalf("failed to add file: %s", err)
}
return nil
})
if walk_err != nil {
log.Fatalf("%s", walk_err)
}
}
err = writer.WriteTo(isoFile, "Test")
if err != nil {
log.Fatalf("failed to write ISO image: %s", err)
}
}
注意事项
- 该库不支持Joliet扩展
- Rock Ridge扩展支持是实验性的,如果遇到问题可以使用v0.3版本
- 创建ISO时需要注意文件名格式,ISO9660标准对文件名有限制(如大写字母、长度等)
更多关于golang读写ISO9660磁盘镜像文件插件库iso9660的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang读写ISO9660磁盘镜像文件插件库iso9660的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 读写 ISO9660 磁盘镜像文件的 iso9660 库使用指南
ISO9660 是 CD-ROM 文件系统的标准格式,在 Go 中可以使用 github.com/kdomanski/iso9660
这个第三方库来处理 ISO9660 镜像文件。
安装 iso9660 库
首先需要安装这个库:
go get github.com/kdomanski/iso9660
读取 ISO9660 镜像文件
1. 打开 ISO 文件并读取内容
package main
import (
"fmt"
"log"
"os"
"github.com/kdomanski/iso9660"
)
func main() {
// 打开 ISO 文件
f, err := os.Open("example.iso")
if err != nil {
log.Fatalf("Failed to open ISO file: %v", err)
}
defer f.Close()
// 读取 ISO 内容
image, err := iso9660.OpenImage(f)
if err != nil {
log.Fatalf("Failed to read ISO image: %v", err)
}
// 获取根目录
root, err := image.RootDir()
if err != nil {
log.Fatalf("Failed to get root directory: %v", err)
}
// 遍历文件系统
err = iso9660.WalkDir(root, func(d *iso9660.File, path string) error {
fmt.Printf("Found: %s (size: %d bytes)\n", path, d.Size())
return nil
})
if err != nil {
log.Fatalf("Failed to walk directory: %v", err)
}
}
2. 提取 ISO 中的文件
func extractFileFromISO(isoPath, filePath, outputPath string) error {
// 打开 ISO 文件
f, err := os.Open(isoPath)
if err != nil {
return fmt.Errorf("failed to open ISO file: %v", err)
}
defer f.Close()
// 读取 ISO 内容
image, err := iso9660.OpenImage(f)
if err != nil {
return fmt.Errorf("failed to read ISO image: %v", err)
}
// 获取根目录
root, err := image.RootDir()
if err != nil {
return fmt.Errorf("failed to get root directory: %v", err)
}
// 查找指定文件
file, err := root.GetEntry(filePath)
if err != nil {
return fmt.Errorf("failed to find file %s: %v", filePath, err)
}
// 创建输出文件
outFile, err := os.Create(outputPath)
if err != nil {
return fmt.Errorf("failed to create output file: %v", err)
}
defer outFile.Close()
// 复制文件内容
_, err = file.CopyTo(outFile)
if err != nil {
return fmt.Errorf("failed to extract file: %v", err)
}
return nil
}
创建 ISO9660 镜像文件
1. 创建简单的 ISO 文件
func createSimpleISO(outputPath string) error {
// 创建临时目录结构
tmpDir, err := os.MkdirTemp("", "iso-example")
if err != nil {
return fmt.Errorf("failed to create temp dir: %v", err)
}
defer os.RemoveAll(tmpDir)
// 在临时目录中创建一些文件
file1 := filepath.Join(tmpDir, "README.txt")
if err := os.WriteFile(file1, []byte("This is a test ISO file"), 0644); err != nil {
return fmt.Errorf("failed to create test file: %v", err)
}
subDir := filepath.Join(tmpDir, "docs")
if err := os.Mkdir(subDir, 0755); err != nil {
return fmt.Errorf("failed to create subdirectory: %v", err)
}
file2 := filepath.Join(subDir, "notes.txt")
if err := os.WriteFile(file2, []byte("Some important notes"), 0644); err != nil {
return fmt.Errorf("failed to create notes file: %v", err)
}
// 创建输出文件
outFile, err := os.Create(outputPath)
if err != nil {
return fmt.Errorf("failed to create output file: %v", err)
}
defer outFile.Close()
// 创建 ISO 写入器
writer, err := iso9660.NewWriter()
if err != nil {
return fmt.Errorf("failed to create ISO writer: %v", err)
}
defer writer.Cleanup()
// 添加目录内容
if err := writer.AddDirectory(tmpDir); err != nil {
return fmt.Errorf("failed to add directory to ISO: %v", err)
}
// 写入 ISO 文件
if err := writer.WriteTo(outFile, "MY_ISO"); err != nil {
return fmt.Errorf("failed to write ISO image: %v", err)
}
return nil
}
2. 高级选项创建 ISO
func createAdvancedISO(outputPath string) error {
// 创建写入器并设置选项
writer, err := iso9660.NewWriterWithOptions(iso9660.WriterConfig{
RockRidge: true, // 启用 Rock Ridge 扩展
VolumeID: "MY_DATA_DISC",
Publisher: "My Company",
DataPreparer: "Go ISO Creator",
})
if err != nil {
return fmt.Errorf("failed to create ISO writer: %v", err)
}
defer writer.Cleanup()
// 手动添加文件
if err := writer.AddFile("README.txt", strings.NewReader("Important information")); err != nil {
return fmt.Errorf("failed to add file: %v", err)
}
// 添加目录
if err := writer.AddDirectory("docs/"); err != nil {
return fmt.Errorf("failed to add directory: %v", err)
}
// 创建输出文件
outFile, err := os.Create(outputPath)
if err != nil {
return fmt.Errorf("failed to create output file: %v", err)
}
defer outFile.Close()
// 写入 ISO
if err := writer.WriteTo(outFile, "ADVANCED_ISO"); err != nil {
return fmt.Errorf("failed to write ISO image: %v", err)
}
return nil
}
注意事项
- 权限问题:ISO9660 有严格的权限限制,创建文件时需要注意
- 文件名限制:标准 ISO9660 文件名限制为 8.3 格式(8字符名+3字符扩展名)
- 扩展支持:可以通过 Rock Ridge 或 Joliet 扩展支持长文件名
- 大文件支持:标准 ISO9660 限制单个文件最大 4GB
总结
github.com/kdomanski/iso9660
库提供了简单易用的 API 来读写 ISO9660 镜像文件。通过这个库,你可以:
- 提取 ISO 镜像中的文件和目录
- 创建新的 ISO 镜像文件
- 自定义 ISO 卷标和元数据
- 支持 Rock Ridge 扩展
以上示例代码涵盖了最常见的用例,你可以根据需要进一步扩展功能。