afero
packagemoduleThis package is not in the latest version of its module.
Details
Validgo.mod file
The Go module system was introduced in Go 1.11 and is the official dependency management solution for Go.
Redistributable license
Redistributable licenses place minimal restrictions on how software can be used, modified, and redistributed.
Tagged version
Modules with tagged versions give importers more predictable builds.
Stable version
When a project reaches major version v1 it is considered stable.
- Learn more about best practices
Repository
Links
README¶

Afero: The Universal Filesystem Abstraction for Go
Afero is a powerful and extensible filesystem abstraction system for Go. It provides a single, unified API for interacting with diverse filesystems—including the local disk, memory, archives, and network storage.
Afero acts as a drop-in replacement for the standardos package, enabling you to write modular code that is agnostic to the underlying storage, dramatically simplifies testing, and allows for sophisticated architectural patterns through filesystem composition.
Why Afero?
Afero elevates filesystem interaction beyond simple file reading and writing, offering solutions for testability, flexibility, and advanced architecture.
🔑Key Features:
- Universal API: Write your code once. Run it against the local OS, in-memory storage, ZIP/TAR archives, or remote systems (SFTP, GCS).
- Ultimate Testability: Utilize
MemMapFs, a fully concurrent-safe, read/write in-memory filesystem. Write fast, isolated, and reliable unit tests without touching the physical disk or worrying about cleanup. - Powerful Composition: Afero's hidden superpower. Layer filesystems on top of each other to create sophisticated behaviors:
- Sandboxing: Use
CopyOnWriteFsto create temporary scratch spaces that isolate changes from the base filesystem. - Caching: Use
CacheOnReadFsto automatically layer a fast cache (like memory) over a slow backend (like a network drive). - Security Jails: Use
BasePathFsto restrict application access to a specific subdirectory (chroot).
- Sandboxing: Use
osPackage Compatibility: Afero mirrors the functions in the standardospackage, making adoption and refactoring seamless.io/fsCompatibility: Fully compatible with the Go standard library'sio/fsinterfaces.
Installation
go get github.com/spf13/aferoimport "github.com/spf13/afero"Quick Start: The Power of Abstraction
The core of Afero is theafero.Fs interface. By designing your functions to accept this interface rather than callingos.* functions directly, your code instantly becomes more flexible and testable.
1. Refactor Your Code
Change functions that rely on theos package to acceptafero.Fs.
// Before: Coupled to the OS and difficult to test// func ProcessConfiguration(path string) error {// data, err := os.ReadFile(path)// ...// }import "github.com/spf13/afero"// After: Decoupled, flexible, and testablefunc ProcessConfiguration(fs afero.Fs, path string) error { // Use Afero utility functions which mirror os/ioutil data, err := afero.ReadFile(fs, path) // ... process the data return err}2. Usage in Production
In your production environment, inject theOsFs backend, which wraps the standard operating system calls.
func main() { // Use the real OS filesystem AppFs := afero.NewOsFs() ProcessConfiguration(AppFs, "/etc/myapp.conf")}3. Usage in Testing
In your tests, injectMemMapFs. This provides a blazing-fast, isolated, in-memory filesystem that requires no disk I/O and no cleanup.
func TestProcessConfiguration(t *testing.T) { // Use the in-memory filesystem AppFs := afero.NewMemMapFs() // Pre-populate the memory filesystem for the test configPath := "/test/config.json" afero.WriteFile(AppFs, configPath, []byte(`{"feature": true}`), 0644) // Run the test entirely in memory err := ProcessConfiguration(AppFs, configPath) if err != nil { t.Fatal(err) }}Afero's Superpower: Composition
Afero's most unique feature is its ability to combine filesystems. This allows you to build complex behaviors out of simple components, keeping your application logic clean.
Example 1: Sandboxing with Copy-on-Write
Create a temporary environment where an application can "modify" system files without affecting the actual disk.
// 1. The base layer is the real OS, made read-only for safety.baseFs := afero.NewReadOnlyFs(afero.NewOsFs())// 2. The overlay layer is a temporary in-memory filesystem for changes.overlayFs := afero.NewMemMapFs()// 3. Combine them. Reads fall through to the base; writes only hit the overlay.sandboxFs := afero.NewCopyOnWriteFs(baseFs, overlayFs)// The application can now "modify" /etc/hosts, but the changes are isolated in memory.afero.WriteFile(sandboxFs, "/etc/hosts", []byte("127.0.0.1 sandboxed-app"), 0644)// The real /etc/hosts on disk is untouched.Example 2: Caching a Slow Filesystem
Improve performance by layering a fast cache (like memory) over a slow backend (like a network drive or cloud storage).
import "time"// Assume 'remoteFs' is a slow backend (e.g., SFTP or GCS)var remoteFs afero.Fs // 'cacheFs' is a fast in-memory backendcacheFs := afero.NewMemMapFs()// Create the caching layer. Cache items for 5 minutes upon first read.cachedFs := afero.NewCacheOnReadFs(remoteFs, cacheFs, 5*time.Minute)// The first read is slow (fetches from remote, then caches)data1, _ := afero.ReadFile(cachedFs, "data.json")// The second read is instant (serves from memory cache)data2, _ := afero.ReadFile(cachedFs, "data.json")Example 3: Security Jails (chroot)
Restrict an application component's access to a specific subdirectory.
osFs := afero.NewOsFs()// Create a filesystem rooted at /home/user/public// The application cannot access anything above this directory.jailedFs := afero.NewBasePathFs(osFs, "/home/user/public")// To the application, this is reading "/"// In reality, it's reading "/home/user/public/"dirInfo, err := afero.ReadDir(jailedFs, "/")// Attempts to access parent directories fail_, err = jailedFs.Open("../secrets.txt") // Returns an errorReal-World Use Cases
Build Cloud-Agnostic Applications
Write applications that seamlessly work with different storage backends:
type DocumentProcessor struct { fs afero.Fs}func NewDocumentProcessor(fs afero.Fs) *DocumentProcessor { return &DocumentProcessor{fs: fs}}func (p *DocumentProcessor) Process(inputPath, outputPath string) error { // This code works whether fs is local disk, cloud storage, or memory content, err := afero.ReadFile(p.fs, inputPath) if err != nil { return err } processed := processContent(content) return afero.WriteFile(p.fs, outputPath, processed, 0644)}// Use with local filesystemprocessor := NewDocumentProcessor(afero.NewOsFs())// Use with Google Cloud Storageprocessor := NewDocumentProcessor(gcsFS)// Use with in-memory filesystem for testingprocessor := NewDocumentProcessor(afero.NewMemMapFs())Treating Archives as Filesystems
Read files directly from.zip or.tar archives without unpacking them to disk first.
import ( "archive/zip" "github.com/spf13/afero/zipfs")// Assume 'zipReader' is a *zip.Reader initialized from a file or memoryvar zipReader *zip.Reader // Create a read-only ZipFsarchiveFS := zipfs.New(zipReader)// Read a file from within the archive using the standard Afero APIcontent, err := afero.ReadFile(archiveFS, "/docs/readme.md")Serving Any Filesystem over HTTP
UseHttpFs to expose any Afero filesystem—even one created dynamically in memory—through a standard Go web server.
import ( "net/http" "github.com/spf13/afero")func main() { memFS := afero.NewMemMapFs() afero.WriteFile(memFS, "index.html", []byte("<h1>Hello from Memory!</h1>"), 0644) // Wrap the memory filesystem to make it compatible with http.FileServer. httpFS := afero.NewHttpFs(memFS) http.Handle("/", http.FileServer(httpFS.Dir("/"))) http.ListenAndServe(":8080", nil)}Testing Made Simple
One of Afero's greatest strengths is making filesystem-dependent code easily testable:
func SaveUserData(fs afero.Fs, userID string, data []byte) error { filename := fmt.Sprintf("users/%s.json", userID) return afero.WriteFile(fs, filename, data, 0644)}func TestSaveUserData(t *testing.T) { // Create a clean, fast, in-memory filesystem for testing testFS := afero.NewMemMapFs() userData := []byte(`{"name": "John", "email": "john@example.com"}`) err := SaveUserData(testFS, "123", userData) if err != nil { t.Fatalf("SaveUserData failed: %v", err) } // Verify the file was saved correctly saved, err := afero.ReadFile(testFS, "users/123.json") if err != nil { t.Fatalf("Failed to read saved file: %v", err) } if string(saved) != string(userData) { t.Errorf("Data mismatch: got %s, want %s", saved, userData) }}Benefits of testing with Afero:
- ⚡Fast - No disk I/O, tests run in memory
- 🔄Reliable - Each test starts with a clean slate
- 🧹No cleanup - Memory is automatically freed
- 🔒Safe - Can't accidentally modify real files
- 🏃Parallel - Tests can run concurrently without conflicts
Backend Reference
| Type | Backend | Constructor | Description | Status |
|---|---|---|---|---|
| Core | OsFs | afero.NewOsFs() | Interacts with the real operating system filesystem. Use in production. | ✅ Official |
| MemMapFs | afero.NewMemMapFs() | A fast, atomic, concurrent-safe, in-memory filesystem. Ideal for testing. | ✅ Official | |
| Composition | CopyOnWriteFs | afero.NewCopyOnWriteFs(base, overlay) | A read-only base with a writable overlay. Ideal for sandboxing. | ✅ Official |
| CacheOnReadFs | afero.NewCacheOnReadFs(base, cache, ttl) | Lazily caches files from a slow base into a fast layer on first read. | ✅ Official | |
| BasePathFs | afero.NewBasePathFs(source, path) | Restricts operations to a subdirectory (chroot/jail). | ✅ Official | |
| ReadOnlyFs | afero.NewReadOnlyFs(source) | Provides a read-only view, preventing any modifications. | ✅ Official | |
| RegexpFs | afero.NewRegexpFs(source, regexp) | Filters a filesystem, only showing files that match a regex. | ✅ Official | |
| Utility | HttpFs | afero.NewHttpFs(source) | Wraps any Afero filesystem to be served viahttp.FileServer. | ✅ Official |
| Archives | ZipFs | zipfs.New(zipReader) | Read-only access to files within a ZIP archive. | ✅ Official |
| TarFs | tarfs.New(tarReader) | Read-only access to files within a TAR archive. | ✅ Official | |
| Network | GcsFs | gcsfs.NewGcsFs(...) | Google Cloud Storage backend. | ⚡ Experimental |
| SftpFs | sftpfs.New(...) | SFTP backend. | ⚡ Experimental | |
| 3rd Party Cloud | S3Fs | fclairamb/afero-s3 | Production-ready S3 backend built on official AWS SDK. | 🔹 3rd Party |
| MinioFs | cpyun/afero-minio | MinIO object storage backend with S3 compatibility. | 🔹 3rd Party | |
| DriveFs | fclairamb/afero-gdrive | Google Drive backend with streaming support. | 🔹 3rd Party | |
| DropboxFs | fclairamb/afero-dropbox | Dropbox backend with streaming support. | 🔹 3rd Party | |
| 3rd Party Specialized | GitFs | tobiash/go-gitfs | Git repository filesystem (read-only, Afero compatible). | 🔹 3rd Party |
| DockerFs | unmango/aferox | Docker container filesystem access. | 🔹 3rd Party | |
| GitHubFs | unmango/aferox | GitHub repository and releases filesystem. | 🔹 3rd Party | |
| FilterFs | unmango/aferox | Filesystem filtering with predicates. | 🔹 3rd Party | |
| IgnoreFs | unmango/aferox | .gitignore-aware filtering filesystem. | 🔹 3rd Party | |
| FUSEFs | JakWai01/sile-fystem | Generic FUSE implementation using any Afero backend. | 🔹 3rd Party |
Afero vs.io/fs (Go 1.16+)
Go 1.16 introduced theio/fs package, which provides a standard abstraction forread-only filesystems.
Afero complementsio/fs by focusing on different needs:
- Use
io/fswhen: You only need to read files and want to conform strictly to the standard library interfaces. - Use Afero when:
- Your application needs tocreate, write, modify, or delete files.
- You need to test complex read/write interactions (e.g., renaming, concurrent writes).
- You need advanced compositional features (Copy-on-Write, Caching, etc.).
Afero is fully compatible withio/fs. You can wrap any Afero filesystem to satisfy thefs.FS interface usingafero.NewIOFS:
import "io/fs"// Create an Afero filesystem (writable)var myAferoFs afero.Fs = afero.NewMemMapFs()// Convert it to a standard library fs.FS (read-only view)var myIoFs fs.FS = afero.NewIOFS(myAferoFs)Third-Party Backends & Ecosystem
The Afero community has developed numerous backends and tools that extend the library's capabilities. Below are curated, well-maintained options organized by maturity and reliability.
Featured Community Backends
These are mature, reliable backends that we can confidently recommend for production use:
Amazon S3 -fclairamb/afero-s3
Production-ready S3 backend built on the official AWS SDK for Go.
import "github.com/fclairamb/afero-s3"s3fs := s3.NewFs(bucket, session)MinIO -cpyun/afero-minio
MinIO object storage backend providing S3-compatible object storage with deduplication and optimization features.
import "github.com/cpyun/afero-minio"minioFs := miniofs.NewMinioFs(ctx, "minio://endpoint/bucket")Community & Specialized Backends
Cloud Storage
Google Drive -
fclairamb/afero-gdrive
Streaming support; no write-seeking or POSIX permissions; no files listing cacheDropbox -
fclairamb/afero-dropbox
Streaming support; no write-seeking or POSIX permissions
Version Control Systems
- Git Repositories -
tobiash/go-gitfs
Read-only filesystem abstraction for Git repositories. Works with bare repositories and provides filesystem view of any git reference. Uses go-git for repository access.
Container and Remote Systems
Docker Containers -
unmango/aferox
Access Docker container filesystems as if they were local filesystemsGitHub API -
unmango/aferox
Turn GitHub repositories, releases, and assets into browsable filesystems
FUSE Integration
- Generic FUSE -
JakWai01/sile-fystem
Mount any Afero filesystem as a FUSE filesystem, allowing any Afero backend to be used as a real mounted filesystem
Specialized Filesystems
- FAT32 Support -
aligator/GoFAT
Pure Go FAT filesystem implementation (currently read-only)
Interface Adapters & Utilities
Cross-Interface Compatibility:
jfontan/go-billy-desfacer- Adapter between Afero and go-billy interfaces (for go-git compatibility)Maldris/go-billy-afero- Alternative wrapper for using Afero with go-billyc4milo/afero2billy- Another Afero to billy filesystem adapter
Working Directory Management:
carolynvs/aferox- Working directory-aware filesystem wrapper
Advanced Filtering:
unmango/aferoxincludes multiple specialized filesystems:- FilterFs - Predicate-based file filtering
- IgnoreFs - .gitignore-aware filtering
- WriterFs - Dump writes to io.Writer for debugging
Developer Tools & Utilities
nhatthm Utility Suite - Essential tools for Afero development:
nhatthm/aferocopy- Copy files between any Afero filesystemsnhatthm/aferomock- Mocking toolkit for testingnhatthm/aferoassert- Assertion helpers for filesystem testing
Ecosystem Showcase
Windows Virtual Drives -balazsgrill/potatodrive
Mount any Afero filesystem as a Windows drive letter. Brilliant demonstration of Afero's power!
Modern Asset Embedding (Go 1.16+)
Instead of third-party tools, use Go's native//go:embed with Afero:
import ( "embed" "github.com/spf13/afero")//go:embed assets/*var assetsFS embed.FSfunc main() { // Convert embedded files to Afero filesystem fs := afero.FromIOFS(assetsFS) // Use like any other Afero filesystem content, _ := afero.ReadFile(fs, "assets/config.json")}Contributing
We welcome contributions! The project is mature, but we are actively looking for contributors to help implement and stabilize network/cloud backends.
- 🔥Microsoft Azure Blob Storage
- 🔒Modern Encryption Backend - Built on secure, contemporary crypto (not legacy EncFS)
- 🐙Canonical go-git Adapter - Unified solution for Git integration
- 📡SSH/SCP Backend - Secure remote file operations
- Stabilization of existing experimental backends (GCS, SFTP)
To contribute:
- Fork the repository
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
📄 License
Afero is released under the Apache 2.0 license. SeeLICENSE.txt for details.
🔗 Additional Resources
Afero comes from the Latin roots Ad-Facere, meaning "to make" or "to do" - fitting for a library that empowers you to make and do amazing things with filesystems.
Documentation¶
Index¶
- Constants
- Variables
- func DirExists(fs Fs, path string) (bool, error)
- func Exists(fs Fs, path string) (bool, error)
- func FileContainsAnyBytes(fs Fs, filename string, subslices [][]byte) (bool, error)
- func FileContainsBytes(fs Fs, filename string, subslice []byte) (bool, error)
- func FullBaseFsPath(basePathFs *BasePathFs, relativePath string) string
- func GetTempDir(fs Fs, subPath string) string
- func Glob(fs Fs, pattern string) (matches []string, err error)
- func IsDir(fs Fs, path string) (bool, error)
- func IsEmpty(fs Fs, path string) (bool, error)
- func NeuterAccents(s string) string
- func ReadAll(r io.Reader) ([]byte, error)
- func ReadDir(fs Fs, dirname string) ([]os.FileInfo, error)
- func ReadFile(fs Fs, filename string) ([]byte, error)
- func SafeWriteReader(fs Fs, path string, r io.Reader) (err error)
- func TempDir(fs Fs, dir, prefix string) (name string, err error)
- func UnicodeSanitize(s string) string
- func Walk(fs Fs, root string, walkFn filepath.WalkFunc) error
- func WriteFile(fs Fs, filename string, data []byte, perm os.FileMode) error
- func WriteReader(fs Fs, path string, r io.Reader) (err error)
- type Afero
- func (a Afero) DirExists(path string) (bool, error)
- func (a Afero) Exists(path string) (bool, error)
- func (a Afero) FileContainsAnyBytes(filename string, subslices [][]byte) (bool, error)
- func (a Afero) FileContainsBytes(filename string, subslice []byte) (bool, error)
- func (a Afero) GetTempDir(subPath string) string
- func (a Afero) IsDir(path string) (bool, error)
- func (a Afero) IsEmpty(path string) (bool, error)
- func (a Afero) ReadDir(dirname string) ([]os.FileInfo, error)
- func (a Afero) ReadFile(filename string) ([]byte, error)
- func (a Afero) SafeWriteReader(path string, r io.Reader) (err error)
- func (a Afero) TempDir(dir, prefix string) (name string, err error)
- func (a Afero) TempFile(dir, pattern string) (f File, err error)
- func (a Afero) Walk(root string, walkFn filepath.WalkFunc) error
- func (a Afero) WriteFile(filename string, data []byte, perm os.FileMode) error
- func (a Afero) WriteReader(path string, r io.Reader) (err error)
- type BasePathFile
- type BasePathFs
- func (b *BasePathFs) Chmod(name string, mode os.FileMode) (err error)
- func (b *BasePathFs) Chown(name string, uid, gid int) (err error)
- func (b *BasePathFs) Chtimes(name string, atime, mtime time.Time) (err error)
- func (b *BasePathFs) Create(name string) (f File, err error)
- func (b *BasePathFs) LstatIfPossible(name string) (os.FileInfo, bool, error)
- func (b *BasePathFs) Mkdir(name string, mode os.FileMode) (err error)
- func (b *BasePathFs) MkdirAll(name string, mode os.FileMode) (err error)
- func (b *BasePathFs) Name() string
- func (b *BasePathFs) Open(name string) (f File, err error)
- func (b *BasePathFs) OpenFile(name string, flag int, mode os.FileMode) (f File, err error)
- func (b *BasePathFs) ReadlinkIfPossible(name string) (string, error)
- func (b *BasePathFs) RealPath(name string) (path string, err error)
- func (b *BasePathFs) Remove(name string) (err error)
- func (b *BasePathFs) RemoveAll(name string) (err error)
- func (b *BasePathFs) Rename(oldname, newname string) (err error)
- func (b *BasePathFs) Stat(name string) (fi os.FileInfo, err error)
- func (b *BasePathFs) SymlinkIfPossible(oldname, newname string) error
- type CacheOnReadFs
- func (u *CacheOnReadFs) Chmod(name string, mode os.FileMode) error
- func (u *CacheOnReadFs) Chown(name string, uid, gid int) error
- func (u *CacheOnReadFs) Chtimes(name string, atime, mtime time.Time) error
- func (u *CacheOnReadFs) Create(name string) (File, error)
- func (u *CacheOnReadFs) Mkdir(name string, perm os.FileMode) error
- func (u *CacheOnReadFs) MkdirAll(name string, perm os.FileMode) error
- func (u *CacheOnReadFs) Name() string
- func (u *CacheOnReadFs) Open(name string) (File, error)
- func (u *CacheOnReadFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
- func (u *CacheOnReadFs) Remove(name string) error
- func (u *CacheOnReadFs) RemoveAll(name string) error
- func (u *CacheOnReadFs) Rename(oldname, newname string) error
- func (u *CacheOnReadFs) Stat(name string) (os.FileInfo, error)
- type CopyOnWriteFs
- func (u *CopyOnWriteFs) Chmod(name string, mode os.FileMode) error
- func (u *CopyOnWriteFs) Chown(name string, uid, gid int) error
- func (u *CopyOnWriteFs) Chtimes(name string, atime, mtime time.Time) error
- func (u *CopyOnWriteFs) Create(name string) (File, error)
- func (u *CopyOnWriteFs) LstatIfPossible(name string) (os.FileInfo, bool, error)
- func (u *CopyOnWriteFs) Mkdir(name string, perm os.FileMode) error
- func (u *CopyOnWriteFs) MkdirAll(name string, perm os.FileMode) error
- func (u *CopyOnWriteFs) Name() string
- func (u *CopyOnWriteFs) Open(name string) (File, error)
- func (u *CopyOnWriteFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
- func (u *CopyOnWriteFs) ReadlinkIfPossible(name string) (string, error)
- func (u *CopyOnWriteFs) Remove(name string) error
- func (u *CopyOnWriteFs) RemoveAll(name string) error
- func (u *CopyOnWriteFs) Rename(oldname, newname string) error
- func (u *CopyOnWriteFs) Stat(name string) (os.FileInfo, error)
- func (u *CopyOnWriteFs) SymlinkIfPossible(oldname, newname string) error
- type DirsMerger
- type File
- type FromIOFS
- func (f FromIOFS) Chmod(name string, mode os.FileMode) error
- func (f FromIOFS) Chown(name string, uid, gid int) error
- func (f FromIOFS) Chtimes(name string, atime time.Time, mtime time.Time) error
- func (f FromIOFS) Create(name string) (File, error)
- func (f FromIOFS) Mkdir(name string, perm os.FileMode) error
- func (f FromIOFS) MkdirAll(path string, perm os.FileMode) error
- func (f FromIOFS) Name() string
- func (f FromIOFS) Open(name string) (File, error)
- func (f FromIOFS) OpenFile(name string, flag int, perm os.FileMode) (File, error)
- func (f FromIOFS) Remove(name string) error
- func (f FromIOFS) RemoveAll(path string) error
- func (f FromIOFS) Rename(oldname, newname string) error
- func (f FromIOFS) Stat(name string) (os.FileInfo, error)
- type Fs
- type HttpFs
- func (h HttpFs) Chmod(name string, mode os.FileMode) error
- func (h HttpFs) Chown(name string, uid, gid int) error
- func (h HttpFs) Chtimes(name string, atime time.Time, mtime time.Time) error
- func (h HttpFs) Create(name string) (File, error)
- func (h HttpFs) Dir(s string) *httpDir
- func (h HttpFs) Mkdir(name string, perm os.FileMode) error
- func (h HttpFs) MkdirAll(path string, perm os.FileMode) error
- func (h HttpFs) Name() string
- func (h HttpFs) Open(name string) (http.File, error)
- func (h HttpFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
- func (h HttpFs) Remove(name string) error
- func (h HttpFs) RemoveAll(path string) error
- func (h HttpFs) Rename(oldname, newname string) error
- func (h HttpFs) Stat(name string) (os.FileInfo, error)
- type IOFS
- type LinkReader
- type Linker
- type Lstater
- type MemMapFs
- func (m *MemMapFs) Chmod(name string, mode os.FileMode) error
- func (m *MemMapFs) Chown(name string, uid, gid int) error
- func (m *MemMapFs) Chtimes(name string, atime time.Time, mtime time.Time) error
- func (m *MemMapFs) Create(name string) (File, error)
- func (m *MemMapFs) List()
- func (m *MemMapFs) LstatIfPossible(name string) (os.FileInfo, bool, error)
- func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error
- func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error
- func (*MemMapFs) Name() string
- func (m *MemMapFs) Open(name string) (File, error)
- func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
- func (m *MemMapFs) Remove(name string) error
- func (m *MemMapFs) RemoveAll(path string) error
- func (m *MemMapFs) Rename(oldname, newname string) error
- func (m *MemMapFs) Stat(name string) (os.FileInfo, error)
- type OsFs
- func (OsFs) Chmod(name string, mode os.FileMode) error
- func (OsFs) Chown(name string, uid, gid int) error
- func (OsFs) Chtimes(name string, atime time.Time, mtime time.Time) error
- func (OsFs) Create(name string) (File, error)
- func (OsFs) LstatIfPossible(name string) (os.FileInfo, bool, error)
- func (OsFs) Mkdir(name string, perm os.FileMode) error
- func (OsFs) MkdirAll(path string, perm os.FileMode) error
- func (OsFs) Name() string
- func (OsFs) Open(name string) (File, error)
- func (OsFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
- func (OsFs) ReadlinkIfPossible(name string) (string, error)
- func (OsFs) Remove(name string) error
- func (OsFs) RemoveAll(path string) error
- func (OsFs) Rename(oldname, newname string) error
- func (OsFs) Stat(name string) (os.FileInfo, error)
- func (OsFs) SymlinkIfPossible(oldname, newname string) error
- type ReadOnlyFs
- func (r *ReadOnlyFs) Chmod(n string, m os.FileMode) error
- func (r *ReadOnlyFs) Chown(n string, uid, gid int) error
- func (r *ReadOnlyFs) Chtimes(n string, a, m time.Time) error
- func (r *ReadOnlyFs) Create(n string) (File, error)
- func (r *ReadOnlyFs) LstatIfPossible(name string) (os.FileInfo, bool, error)
- func (r *ReadOnlyFs) Mkdir(n string, p os.FileMode) error
- func (r *ReadOnlyFs) MkdirAll(n string, p os.FileMode) error
- func (r *ReadOnlyFs) Name() string
- func (r *ReadOnlyFs) Open(n string) (File, error)
- func (r *ReadOnlyFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
- func (r *ReadOnlyFs) ReadDir(name string) ([]os.FileInfo, error)
- func (r *ReadOnlyFs) ReadlinkIfPossible(name string) (string, error)
- func (r *ReadOnlyFs) Remove(n string) error
- func (r *ReadOnlyFs) RemoveAll(p string) error
- func (r *ReadOnlyFs) Rename(o, n string) error
- func (r *ReadOnlyFs) Stat(name string) (os.FileInfo, error)
- func (r *ReadOnlyFs) SymlinkIfPossible(oldname, newname string) error
- type RegexpFile
- func (f *RegexpFile) Close() error
- func (f *RegexpFile) Name() string
- func (f *RegexpFile) Read(s []byte) (int, error)
- func (f *RegexpFile) ReadAt(s []byte, o int64) (int, error)
- func (f *RegexpFile) Readdir(c int) (fi []os.FileInfo, err error)
- func (f *RegexpFile) Readdirnames(c int) (n []string, err error)
- func (f *RegexpFile) Seek(o int64, w int) (int64, error)
- func (f *RegexpFile) Stat() (os.FileInfo, error)
- func (f *RegexpFile) Sync() error
- func (f *RegexpFile) Truncate(s int64) error
- func (f *RegexpFile) Write(s []byte) (int, error)
- func (f *RegexpFile) WriteAt(s []byte, o int64) (int, error)
- func (f *RegexpFile) WriteString(s string) (int, error)
- type RegexpFs
- func (r *RegexpFs) Chmod(name string, mode os.FileMode) error
- func (r *RegexpFs) Chown(name string, uid, gid int) error
- func (r *RegexpFs) Chtimes(name string, a, m time.Time) error
- func (r *RegexpFs) Create(name string) (File, error)
- func (r *RegexpFs) Mkdir(n string, p os.FileMode) error
- func (r *RegexpFs) MkdirAll(n string, p os.FileMode) error
- func (r *RegexpFs) Name() string
- func (r *RegexpFs) Open(name string) (File, error)
- func (r *RegexpFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
- func (r *RegexpFs) Remove(name string) error
- func (r *RegexpFs) RemoveAll(p string) error
- func (r *RegexpFs) Rename(oldname, newname string) error
- func (r *RegexpFs) Stat(name string) (os.FileInfo, error)
- type Symlinker
- type UnionFile
- func (f *UnionFile) Close() error
- func (f *UnionFile) Name() string
- func (f *UnionFile) Read(s []byte) (int, error)
- func (f *UnionFile) ReadAt(s []byte, o int64) (int, error)
- func (f *UnionFile) Readdir(c int) (ofi []os.FileInfo, err error)
- func (f *UnionFile) Readdirnames(c int) ([]string, error)
- func (f *UnionFile) Seek(o int64, w int) (pos int64, err error)
- func (f *UnionFile) Stat() (os.FileInfo, error)
- func (f *UnionFile) Sync() (err error)
- func (f *UnionFile) Truncate(s int64) (err error)
- func (f *UnionFile) Write(s []byte) (n int, err error)
- func (f *UnionFile) WriteAt(s []byte, o int64) (n int, err error)
- func (f *UnionFile) WriteString(s string) (n int, err error)
Constants¶
const BADFD =syscall.EBADFDconst FilePathSeparator =string(filepath.Separator)Filepath separator defined by os.Separator.
Variables¶
var (ErrFileClosed =errors.New("File is closed")ErrOutOfRange =errors.New("out of range")ErrTooLarge =errors.New("too large")ErrFileNotFound =os.ErrNotExistErrFileExists =os.ErrExistErrDestinationExists =os.ErrExist)
var ErrNoReadlink =errors.New("readlink not supported")ErrNoReadlink is the error that will be wrapped in an os.Path if a file systemdoes not support the readlink operation either directly or through its delegated filesystem.As expressed by support for the LinkReader interface.
var ErrNoSymlink =errors.New("symlink not supported")ErrNoSymlink is the error that will be wrapped in an os.LinkError if a file systemdoes not support Symlink's either directly or through its delegated filesystem.As expressed by support for the Linker interface.
Functions¶
funcFileContainsAnyBytes¶
Check if a file contains any of the specified byte slices.
funcFileContainsBytes¶
Check if a file contains a specified byte slice.
funcFullBaseFsPath¶
func FullBaseFsPath(basePathFs *BasePathFs, relativePathstring)string
funcGetTempDir¶
GetTempDir returns the default temp directory with trailing slashif subPath is not empty then it will be created recursively with mode 777 rwx rwx rwx
funcGlob¶
Glob returns the names of all files matching pattern or nilif there is no matching file. The syntax of patterns is the sameas in Match. The pattern may describe hierarchical names such as/usr/*/bin/ed (assuming the Separator is '/').
Glob ignores file system errors such as I/O errors reading directories.The only possible returned error is ErrBadPattern, when patternis malformed.
This was adapted from (http://golang.org/pkg/path/filepath) and uses severalbuilt-ins from that package.
funcNeuterAccents¶
Transform characters with accents into plain forms.
funcReadAll¶
ReadAll reads from r until an error or EOF and returns the data it read.A successful call returns err == nil, not err == EOF. Because ReadAll isdefined to read from src until EOF, it does not treat an EOF from Readas an error to be reported.
funcUnicodeSanitize¶
Rewrite string to remove non-standard path characters
Types¶
typeAfero¶
type Afero struct {Fs}func (Afero)FileContainsAnyBytes¶
func (Afero)FileContainsBytes¶
func (Afero)GetTempDir¶
func (Afero)ReadDir¶
ReadDir reads the directory named by dirname and returnsa list of sorted directory entries.
func (Afero)ReadFile¶
ReadFile reads the file named by filename and returns the contents.A successful call returns err == nil, not err == EOF. Because ReadFilereads the whole file, it does not treat an EOF from Read as an errorto be reported.
func (Afero)SafeWriteReader¶
Same as WriteReader but checks to see if file/directory already exists.
func (Afero)TempDir¶
TempDir creates a new temporary directory in the directory dirwith a name beginning with prefix and returns the path of thenew directory. If dir is the empty string, TempDir uses thedefault directory for temporary files (see os.TempDir).Multiple programs calling TempDir simultaneouslywill not choose the same directory. It is the caller's responsibilityto remove the directory when no longer needed.
func (Afero)TempFile¶
TempFile creates a new temporary file in the directory dir,opens the file for reading and writing, and returns the resulting *os.File.The filename is generated by taking pattern and adding a randomstring to the end. If pattern includes a "*", the random stringreplaces the last "*".If dir is the empty string, TempFile uses the default directoryfor temporary files (see os.TempDir).Multiple programs calling TempFile simultaneouslywill not choose the same file. The caller can use f.Name()to find the pathname of the file. It is the caller's responsibilityto remove the file when no longer needed.
typeBasePathFile¶added inv1.1.0
type BasePathFile struct {File// contains filtered or unexported fields}func (*BasePathFile)Name¶added inv1.1.0
func (f *BasePathFile) Name()string
typeBasePathFs¶
type BasePathFs struct {// contains filtered or unexported fields}The BasePathFs restricts all operations to a given path within an Fs.The given file name to the operations on this Fs will be prepended withthe base path before calling the base Fs.Any file name (after filepath.Clean()) outside this base path will betreated as non existing file.
Note that it does not clean the error messages on return, so you mayreveal the real path on errors.
func (*BasePathFs)Chown¶added inv1.5.0
func (b *BasePathFs) Chown(namestring, uid, gidint) (errerror)
func (*BasePathFs)Chtimes¶
func (b *BasePathFs) Chtimes(namestring, atime, mtimetime.Time) (errerror)
func (*BasePathFs)LstatIfPossible¶added inv1.1.0
func (*BasePathFs)Name¶
func (b *BasePathFs) Name()string
func (*BasePathFs)ReadlinkIfPossible¶added inv1.3.0
func (b *BasePathFs) ReadlinkIfPossible(namestring) (string,error)
func (*BasePathFs)RealPath¶
func (b *BasePathFs) RealPath(namestring) (pathstring, errerror)
on a file outside the base path it returns the given file name and an error,else the given file with the base path prepended
func (*BasePathFs)Remove¶
func (b *BasePathFs) Remove(namestring) (errerror)
func (*BasePathFs)RemoveAll¶
func (b *BasePathFs) RemoveAll(namestring) (errerror)
func (*BasePathFs)Rename¶
func (b *BasePathFs) Rename(oldname, newnamestring) (errerror)
func (*BasePathFs)SymlinkIfPossible¶added inv1.3.0
func (b *BasePathFs) SymlinkIfPossible(oldname, newnamestring)error
typeCacheOnReadFs¶
type CacheOnReadFs struct {// contains filtered or unexported fields}If the cache duration is 0, cache time will be unlimited, i.e. oncea file is in the layer, the base will never be read again for this file.
For cache times greater than 0, the modification time of a file ischecked. Note that a lot of file system implementations only allow aresolution of a second for timestamps... or as the godoc for os.Chtimes()states: "The underlying filesystem may truncate or round the values to aless precise time unit."
This caching union will forward all write calls also to the base filesystem first. To prevent writing to the base Fs, wrap it in a read-onlyfilter - Note: this will also make the overlay read-only, for writing filesin the overlay, use the overlay Fs directly, not via the union Fs.
func (*CacheOnReadFs)Chown¶added inv1.5.0
func (u *CacheOnReadFs) Chown(namestring, uid, gidint)error
func (*CacheOnReadFs)Chtimes¶
func (u *CacheOnReadFs) Chtimes(namestring, atime, mtimetime.Time)error
func (*CacheOnReadFs)Name¶
func (u *CacheOnReadFs) Name()string
func (*CacheOnReadFs)Remove¶
func (u *CacheOnReadFs) Remove(namestring)error
func (*CacheOnReadFs)RemoveAll¶
func (u *CacheOnReadFs) RemoveAll(namestring)error
func (*CacheOnReadFs)Rename¶
func (u *CacheOnReadFs) Rename(oldname, newnamestring)error
typeCopyOnWriteFs¶
type CopyOnWriteFs struct {// contains filtered or unexported fields}The CopyOnWriteFs is a union filesystem: a read only base file system witha possibly writeable layer on top. Changes to the file system will onlybe made in the overlay: Changing an existing file in the base layer whichis not present in the overlay will copy the file to the overlay ("changing"includes also calls to e.g. Chtimes(), Chmod() and Chown()).
Reading directories is currently only supported via Open(), not OpenFile().
func (*CopyOnWriteFs)Chown¶added inv1.5.0
func (u *CopyOnWriteFs) Chown(namestring, uid, gidint)error
func (*CopyOnWriteFs)Chtimes¶
func (u *CopyOnWriteFs) Chtimes(namestring, atime, mtimetime.Time)error
func (*CopyOnWriteFs)LstatIfPossible¶added inv1.1.0
func (*CopyOnWriteFs)Name¶
func (u *CopyOnWriteFs) Name()string
func (*CopyOnWriteFs)Open¶
func (u *CopyOnWriteFs) Open(namestring) (File,error)
This function handles the 9 different possibilities causedby the union which are the intersection of the following...
layer: doesn't exist, exists as a file, and exists as a directorybase: doesn't exist, exists as a file, and exists as a directory
func (*CopyOnWriteFs)ReadlinkIfPossible¶added inv1.3.0
func (u *CopyOnWriteFs) ReadlinkIfPossible(namestring) (string,error)
func (*CopyOnWriteFs)Remove¶
func (u *CopyOnWriteFs) Remove(namestring)error
Removing files present only in the base layer is not permitted. Ifa file is present in the base layer and the overlay, only the overlaywill be removed.
func (*CopyOnWriteFs)RemoveAll¶
func (u *CopyOnWriteFs) RemoveAll(namestring)error
func (*CopyOnWriteFs)Rename¶
func (u *CopyOnWriteFs) Rename(oldname, newnamestring)error
Renaming files present only in the base layer is not permitted
func (*CopyOnWriteFs)SymlinkIfPossible¶added inv1.3.0
func (u *CopyOnWriteFs) SymlinkIfPossible(oldname, newnamestring)error
typeDirsMerger¶added inv1.1.0
DirsMerger is how UnionFile weaves two directories together.It takes the FileInfo slices from the layer and the base and returns asingle view.
typeFile¶
type File interface {io.Closerio.Readerio.ReaderAtio.Seekerio.Writerio.WriterAtName()stringReaddir(countint) ([]os.FileInfo,error)Readdirnames(nint) ([]string,error)Stat() (os.FileInfo,error)Sync()errorTruncate(sizeint64)errorWriteString(sstring) (retint, errerror)}File represents a file in the filesystem.
typeFromIOFS¶added inv1.6.0
FromIOFS adopts io/fs.FS to use it as afero.FsNote that io/fs.FS is read-only so all mutating methods will return fs.PathError with fs.ErrPermissionTo store modifications you may use afero.CopyOnWriteFs
typeFs¶
type Fs interface {// Create creates a file in the filesystem, returning the file and an// error, if any happens.Create(namestring) (File,error)// Mkdir creates a directory in the filesystem, return an error if any// happens.Mkdir(namestring, permos.FileMode)error// MkdirAll creates a directory path and all parents that does not exist// yet.MkdirAll(pathstring, permos.FileMode)error// Open opens a file, returning it or an error, if any happens.Open(namestring) (File,error)// OpenFile opens a file using the given flags and the given mode.OpenFile(namestring, flagint, permos.FileMode) (File,error)// Remove removes a file identified by name, returning an error, if any// happens.Remove(namestring)error// RemoveAll removes a directory path and any children it contains. It// does not fail if the path does not exist (return nil).RemoveAll(pathstring)error// Rename renames a file.Rename(oldname, newnamestring)error// Stat returns a FileInfo describing the named file, or an error, if any// happens.Stat(namestring) (os.FileInfo,error)// The name of this FileSystemName()string// Chmod changes the mode of the named file to mode.Chmod(namestring, modeos.FileMode)error// Chown changes the uid and gid of the named file.Chown(namestring, uid, gidint)error// Chtimes changes the access and modification times of the named fileChtimes(namestring, atimetime.Time, mtimetime.Time)error}Fs is the filesystem interface.
Any simulated or real filesystem should implement this interface.
funcNewBasePathFs¶
funcNewMemMapFs¶
func NewMemMapFs()Fs
funcNewReadOnlyFs¶
typeLinkReader¶added inv1.3.0
LinkReader is an optional interface in Afero. It is only implemented by thefilesystems saying so.
typeLinker¶added inv1.3.0
Linker is an optional interface in Afero. It is only implemented by thefilesystems saying so.It will call Symlink if the filesystem itself is, or it delegates to, the os filesystem,or the filesystem otherwise supports Symlink's.
typeLstater¶added inv1.1.0
Lstater is an optional interface in Afero. It is only implemented by thefilesystems saying so.It will call Lstat if the filesystem itself is, or it delegates to, the os filesystem.Else it will call Stat.In addition to the FileInfo, it will return a boolean telling whether Lstat was called or not.
typeMemMapFs¶
type MemMapFs struct {// contains filtered or unexported fields}func (*MemMapFs)LstatIfPossible¶added inv1.4.0
typeOsFs¶
type OsFs struct{}OsFs is a Fs implementation that uses functions provided by the os package.
For details in any method, check the documentation of the os package(http://golang.org/pkg/os/).
func (OsFs)LstatIfPossible¶added inv1.1.0
func (OsFs)ReadlinkIfPossible¶added inv1.3.0
func (OsFs)SymlinkIfPossible¶added inv1.3.0
typeReadOnlyFs¶
type ReadOnlyFs struct {// contains filtered or unexported fields}func (*ReadOnlyFs)LstatIfPossible¶added inv1.1.0
func (*ReadOnlyFs)Name¶
func (r *ReadOnlyFs) Name()string
func (*ReadOnlyFs)ReadlinkIfPossible¶added inv1.3.0
func (r *ReadOnlyFs) ReadlinkIfPossible(namestring) (string,error)
func (*ReadOnlyFs)Remove¶
func (r *ReadOnlyFs) Remove(nstring)error
func (*ReadOnlyFs)RemoveAll¶
func (r *ReadOnlyFs) RemoveAll(pstring)error
func (*ReadOnlyFs)Rename¶
func (r *ReadOnlyFs) Rename(o, nstring)error
func (*ReadOnlyFs)SymlinkIfPossible¶added inv1.3.0
func (r *ReadOnlyFs) SymlinkIfPossible(oldname, newnamestring)error
typeRegexpFile¶
type RegexpFile struct {// contains filtered or unexported fields}func (*RegexpFile)Close¶
func (f *RegexpFile) Close()error
func (*RegexpFile)Name¶
func (f *RegexpFile) Name()string
func (*RegexpFile)Readdirnames¶
func (f *RegexpFile) Readdirnames(cint) (n []string, errerror)
func (*RegexpFile)Sync¶
func (f *RegexpFile) Sync()error
func (*RegexpFile)Truncate¶
func (f *RegexpFile) Truncate(sint64)error
func (*RegexpFile)WriteString¶
func (f *RegexpFile) WriteString(sstring) (int,error)
typeRegexpFs¶
type RegexpFs struct {// contains filtered or unexported fields}The RegexpFs filters files (not directories) by regular expression. Onlyfiles matching the given regexp will be allowed, all others get a ENOENT error ("No such file or directory").
typeSymlinker¶added inv1.3.0
type Symlinker interface {LstaterLinkerLinkReader}Symlinker is an optional interface in Afero. It is only implemented by thefilesystems saying so.It indicates support for 3 symlink related interfaces that implement thebehaviors of the os methods:
- Lstat
- Symlink, and
- Readlink
typeUnionFile¶
type UnionFile struct {BaseFileLayerFileMergerDirsMerger// contains filtered or unexported fields}The UnionFile implements the afero.File interface and will be returnedwhen reading a directory present at least in the overlay or opening a filefor writing.
The calls toReaddir() and Readdirnames() merge the file os.FileInfo / names from thebase and the overlay - for files present in both layers, only thosefrom the overlay will be used.
When opening files for writing (Create() / OpenFile() with the right flags)the operations will be done in both layers, starting with the overlay. Asuccessful read in the overlay will move the cursor position in the base layerby the number of bytes read.