Go library for reading and writing classic HFS, HFS+, and HFSX volumes, plus command-line tools to create and dump disk images.
HFS-Go is a port of DiscUtils HFS+ (and related disk/partition pieces) and machfs to Go.
Requires Go 1.22 or later.
go get github.com/ObsoleteMadness/HFS-Go@latest
go install github.com/ObsoleteMadness/HFS-Go/cmd/DumpHFS@latest
go install github.com/ObsoleteMadness/HFS-Go/cmd/MakeHFS@latestFrom a clone:
git clone https://github.com/ObsoleteMadness/HFS-Go.git
cd HFS-Go
go test ./...Versioned releases are semver tags on main (v1.2.3). go get that tag, or
download DumpHFS / MakeHFS binaries from GitHub Releases.
Mount an existing image (raw .hfv / .dsk, or .dmg):
package main
import (
"fmt"
"log"
hfsgo "github.com/ObsoleteMadness/HFS-Go"
"github.com/ObsoleteMadness/HFS-Go/vfs"
)
func main() {
fs, err := hfsgo.Mount("disk.hfv", false)
if err != nil {
log.Fatal(err)
}
defer fs.Close()
entries, err := fs.ReadDir("")
if err != nil {
log.Fatal(err)
}
for _, e := range entries {
fmt.Println(e.Name)
}
f, err := fs.OpenFile("Read Me", vfs.DataFork, 0)
if err != nil {
log.Fatal(err)
}
defer f.Close()
}Create a blank volume:
import (
"log"
"time"
hfsgo "github.com/ObsoleteMadness/HFS-Go"
)
if err := hfsgo.CreateImage("untitled.hfv", 800*1024, "untitled", "hfs", time.Time{}); err != nil {
log.Fatal(err)
}CreateImage accepts "hfs", "hfsplus", or "hfsx". Mount with writable == true returns a vfs.FS that can create files and directories, open data or resource forks, and set Mac type/creator metadata.
Import a narrower package when you do not want the root convenience API:
| Package | Role |
|---|---|
github.com/ObsoleteMadness/HFS-Go |
Open, mount, format, create images |
.../vfs |
Mac-aware FS (forks, type/creator) |
.../disk |
Raw/DMG virtual disks and Content |
.../volume |
Partition vs volume-only scan |
.../hfs, .../hfsplus |
Filesystem implementations |
.../folder |
Native folder ↔ volume copy (.idump / .rdump) |
.../part/apm |
Apple Partition Map |
Blank-import a plugin if you use disk or vfs without the root package:
import _ "github.com/ObsoleteMadness/HFS-Go/hfsplus"
import _ "github.com/ObsoleteMadness/HFS-Go/disk/raw"These tools copy a native folder into an HFS image and back, using the same sidecar convention as machfs so type/creator codes and resource forks can live in Git.
| Sidecar | Contents |
|---|---|
file.idump |
8 bytes: 4-byte type + 4-byte creator |
file.rdump |
Resource fork (raw bytes) |
Files of type TEXT or ttro are stored on the volume as Mac Roman with CR line endings, and on the native side as UTF-8 with LF.
Create a new image, or format an existing one, and optionally copy a folder into it.
Usage: MakeHFS [options] OUTPUT
-n, -name string
volume name (default "untitled")
-i, -dir string
folder to copy into the image
-s, -size string
volume size (default: sized for OUTPUT, or 800k)
-d, -date string
creation & mod date (ISO-8601 or "now") (default "1994")
-f, -filesystem string
filesystem: hfs, hfsplus, or hfsx (default "hfs")
-mpw-dates
set on-disk dates 1 minute apart in modification order, so MPW Make can decide what to rebuild
Size suffixes: k, m, g, t (also KiB, MiB, …). If OUTPUT already exists and -size is omitted, the existing file is formatted in place.
go run ./cmd/MakeHFS -n "My Disk" -i ./src -s 800k disk.hfv
go run ./cmd/MakeHFS -f hfsplus -n "Plus" -s 10M plus.hfvExtract a volume to a native directory (sidecars included). Desktop files are skipped.
Usage: DumpHFS INPUT OUTPUT
go run ./cmd/DumpHFS disk.hfv ./outHFS-Go is based on:
- DiscUtils — .NET library for virtual disks and file systems, originally by Kenneth Bell, later maintained by Quamotion and the DiscUtils project. HFS+, Apple Partition Map, DMG, and the disk/volume layer here are ports of that work.
- machfs — Python library for classic HFS volumes by Elliot Nunn. Classic HFS layout, catalog sort order, and the MakeHFS / DumpHFS sidecar workflow come from machfs.
Licensed under the MIT License. See LICENSE.