osfs provides an absfs FileSystem implementation that wraps the Go standard library's os package for direct operating system filesystem access.
- Native OS Access: Direct access to your operating system's filesystem
- Cross-Platform Support: Works on Unix, macOS, and Windows
- Windows Drive Mapping:
WindowsDriveMapperfor seamless Unix-style paths on Windows - Full absfs Compatibility: Implements the complete absfs.FileSystem interface
go get github.com/absfs/osfspackage main
import (
"log"
"github.com/absfs/osfs"
)
func main() {
fs, err := osfs.NewFS()
if err != nil {
log.Fatal(err)
}
// Create and write to a file
f, err := fs.Create("example.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
_, err = f.Write([]byte("Hello, world!\n"))
if err != nil {
log.Fatal(err)
}
}For applications that need to work across Unix and Windows, use the build tag pattern with WindowsDriveMapper:
Create filesystem_windows.go:
//go:build windows
package myapp
import "github.com/absfs/osfs"
func NewFS(drive string) absfs.FileSystem {
if drive == "" {
drive = "C:"
}
fs, _ := osfs.NewFS()
return osfs.NewWindowsDriveMapper(fs, drive)
}Create filesystem_unix.go:
//go:build !windows
package myapp
import "github.com/absfs/osfs"
func NewFS(drive string) absfs.FileSystem {
fs, _ := osfs.NewFS()
return fs
}Use it everywhere:
package main
import "myapp"
func main() {
fs := myapp.NewFS("")
// Works identically on all platforms!
fs.Create("/config/app.json") // → /config/app.json on Unix, C:\config\app.json on Windows
fs.MkdirAll("/var/log/app", 0755) // → /var/log/app on Unix, C:\var\log\app on Windows
}See the absfs PATH_HANDLING.md guide for complete cross-platform patterns.
The WindowsDriveMapper enables Unix-style absolute paths on Windows by translating virtual-absolute paths to Windows drive paths:
fs, _ := osfs.NewFS()
mapped := osfs.NewWindowsDriveMapper(fs, "C:")
// Unix-style paths work on Windows
mapped.Create("/tmp/config.json") // Creates C:\tmp\config.json
mapped.MkdirAll("/var/log", 0755) // Creates C:\var\log
// OS-absolute paths pass through unchanged
mapped.Open("C:\\Windows\\file.txt") // Opens C:\Windows\file.txt
mapped.Open("\\\\server\\share\\f") // Opens UNC path \\server\share\f| Input Path | Windows Result | Notes |
|---|---|---|
/config/app.json |
C:\config\app.json |
Virtual-absolute → mapped to drive |
C:\Windows\file |
C:\Windows\file |
OS-absolute → pass through |
\\server\share\f |
\\server\share\f |
UNC path → pass through |
relative/path |
relative\path |
Relative → pass through |
The osfs package provides full symbolic link support via the absfs.SymLinker interface:
fs, _ := osfs.NewFS()
// Create a symlink
fs.Symlink("/path/to/target", "/path/to/link")
// Read symlink target
target, _ := fs.Readlink("/path/to/link")
// Get symlink info without following
info, _ := fs.Lstat("/path/to/link")Windows users: Symlinks require elevated privileges or Developer Mode. See SYMLINKS.md for configuration instructions and platform-specific behavior.
// Standard OS filesystem
fs, err := osfs.NewFS()
// With Windows drive mapping (Windows only)
mapped := osfs.NewWindowsDriveMapper(fs, "D:")// Open files
f, err := fs.Open("/path/to/file.txt")
f, err := fs.Create("/path/to/new.txt")
f, err := fs.OpenFile("/path", os.O_RDWR|os.O_CREATE, 0644)
// File info
info, err := fs.Stat("/path/to/file.txt")
// Remove files
err = fs.Remove("/path/to/file.txt")// Create directories
err = fs.Mkdir("/path/to/dir", 0755)
err = fs.MkdirAll("/path/to/nested/dirs", 0755)
// Remove directories
err = fs.Remove("/empty/dir")
err = fs.RemoveAll("/path/to/dir")// Rename/move
err = fs.Rename("/old/path", "/new/path")
// Permissions and attributes
err = fs.Chmod("/path/to/file", 0644)
err = fs.Chtimes("/path/to/file", atime, mtime)
err = fs.Chown("/path/to/file", uid, gid)
// Working directory
err = fs.Chdir("/new/directory")
cwd, err := fs.Getwd()See example_drivemapper_test.go for complete Windows drive mapping examples.
For advanced directory traversal operations on absfs filesystems, use the fstools package:
import (
"github.com/absfs/fstools"
"github.com/absfs/osfs"
)
fs, _ := osfs.NewFS()
// Simple walk compatible with filepath.WalkFunc
err := fstools.Walk(fs, "/path", func(path string, info os.FileInfo, err error) error {
fmt.Println(path)
return nil
})
// Walk with options for different traversal strategies
options := &fstools.Options{
Sort: true,
Traversal: fstools.BreadthTraversal, // Also: PreOrder, PostOrder, KeyOrder
}
err = fstools.WalkWithOptions(fs, options, "/path", walkFunc)The fstools package provides:
- Multiple traversal strategies: PreOrder, PostOrder, BreadthFirst, and KeyOrder (files only)
- Sorting options: Custom sort functions or alphabetical
- Filesystem operations: Copy, Describe, Diff, Patch, and Apply
- Works with any absfs.Filer implementation
See github.com/absfs/fstools for complete documentation.
- SYMLINKS.md - Symbolic link support and Windows configuration
- absfs Documentation - Main abstraction interface
- PATH_HANDLING.md - Cross-platform path handling
- USER_GUIDE.md - Complete usage guide
- GoDoc - API reference
- absfs - Core filesystem abstraction
- fstools - Advanced filesystem operations (Walk, Copy, Diff, Patch)
- memfs - In-memory filesystem
- basefs - Chroot filesystem wrapper
- rofs - Read-only filesystem wrapper
This project is governed by the MIT License. See LICENSE