Categorygithub.com/ungerik/go-fs
modulepackage
0.0.0-20250310161700-3b05d22755dd
Repository: https://github.com/ungerik/go-fs.git
Documentation: pkg.go.dev

# README

go-fs: A unified file system for Go

Go Reference

The package is built around a File type that is a string underneath and interprets its value as a local file system path or as a URI.

TODO

  • MemFileSystem
  • ZipFileSystem
  • Return ErrFileSystemClosed from all closable FS
  • S3
  • Test dropboxfs
  • Test fptfs
  • TestFileReads and TestFileMetaData for all FS
  • add TestFileWrites

Introduction

FileSystem implementations can be registered with their URI qualifiers like file:// or http://.

The methods of File parse their string value for a qualifier and look up a FileSystem in the Registry. The only special rule is, that if no qualifier is present, then the string value is interpreted as a local file path.

The LocalFileSystem is registered by default.

Work with Local directly:

fs.Local.Separator() // Either `/` or `\`

fs.Local.IsSymbolicLink("~/file") // Tilde expands to user home dir

For example, create a FileSystem from a multi-part HTTP form request that contains an uploaded file:

import "github.com/ungerik/go-fs/multipartfs"

multipartFS, err := multipartfs.FromRequestForm(request, MaxUploadSize)

defer multipartFS.Close()

// Access form values as string
multipartFS.Form.Value["email"] 

// Access form files as fs.File
file, err := multipartFS.FormFile("file")

// Use like any other fs.File
bytes, err := file.ReadAll(ctx)

fs.File

type File string

As a string-type it's easy to assign string literals and it can be const which would be impossible if File was an interface or struct:

const fileConst fs.File = "~/file.a"

var fileVar fs.File = "~/file.b"

fileVar = fileConst
fileVar = "~/file.c"

Handy to pass string literals of local paths or URIs to functions:

func readFile(f fs.File) { /* ... */ }

readFile("../my-local-file.txt")

// HTTP reading works when httpfs is imported
import _ "github.com/ungerik/go-fs/httpfs"

readFile("https://example.com/file-via-uri.txt")

As a string type File naturally marshals/unmarshals as string path/URI without having to implement marshaling interfaces.

But it implements fmt.Stringer to add the name of the path/URI filesystem as debug information and gob.GobEncoder, gob.GobDecoder to encode filename and content instead of the path/URI value.

Path related methods:

file := fs.TempDir().Join("file.txt")

dir := file.Dir()   // "/tmp" == fs.TempDir()
name := file.Name() // "file.txt"
path := file.Path() // "/tmp/file.txt"
url := file.URL()   // "file:///tmp/file.txt"
ext := file.Ext()   // ".txt"

file2 := file.Dir().Join("a", "b", "c").Joinf("file%d.txt", 2)
path2 := file2.Path() // "/tmp/a/b/c/file2.txt"

abs := fs.File("~/some-dir/../file").AbsPath() // "/home/erik/file"

Meta information:

size := file.Size() // int64, 0 for non existing or dirs
isDir := dir.IsDir()      // true
exists := file.Exists()   // true
fileIsDir := file.IsDir() // false
modTime := file.ModTime()
hash, err := file.ContentHash()  // Dropbox hash algo
regular := file.Info().IsRegular // true
info := file.Info().FSFileInfo() // io/fs.FileInfo

Reading and writing files

Reading:

bytes, err := file.ReadAll(ctx)

str, err := file.ReadAllString(ctx)

var w io.Writer
n, err := file.WriteTo(w)

f, err := file.OpenReader()     // io/fs.File 
r, err := file.OpenReadSeeker() // fs.ReadSeekCloser

Writing:

err := file.WriteAll(ctx, []byte("Hello"))

err := file.WriteAllString(ctx, "Hello")

err := file.Append(ctx, []byte("Hello"))

err := file.AppendString(ctx, "Hello")

var r io.Reader
n, err := file.ReadFrom(r)

w, err := file.OpenWriter()       // io.WriteCloser
w, err := file.OpenAppendWriter() // io.WriteCloser

rw, err := file.OpenReadWriter() // fs.ReadWriteSeekCloser

fs.FileReader

For cases where a file should be passed only for reading, it's recommended to use the interface type FileReader. It has all the read-related methods of File, so a File can be assigned or passed as FileReader:

type FileReader interface { /* ... */ }
func readFile(f fs.FileReader) { /* ... */ }

// An untyped string literal does not work as interface,
// needs a concrete type like fs.File
readFile(fs.File("../my-local-file.txt"))

fs.MemFile

MemFile combines the buffered in-memory data of a file with a filename to implement fs.FileReader. It exposes FileName and FileData as exported struct fields to emphasize its simple nature as just a wrapper of a name and some bytes.

type MemFile struct {
	FileName string
	FileData []byte
}

The type exists because it's very common to build up a file in memory and/or pass around some buffered file bytes together with a filename:

func readFile(f fs.FileReader) { /* ... */ }

readFile(fs.NewMemFile("hello-world.txt", []byte("Hello World!")))

// Read another fs.FileReader into a fs.MemFile
// to have it buffered in memory
memFile, err := fs.ReadMemFile(ctx, fs.File("../my-local-file.txt"))

// Read all data similar to io.ReadAll from an io.Reader
var r io.Rader
memFile, err := fs.ReadAllMemFile(cxt, r, "in-mem-file.txt")

Note that MemFile is not a File because it doesn't have a path or URI. The in-memory FileName is not interpreted as a path and should not contain path separators.

Listing directories

// Print names of all JPEGs in dir
dir.ListDir(func(f fs.File) error {
	_, err := fmt.Println(f.Name())
	return err
})

// Print names of all JPEGs in dir and all recursive sub-dirs
// with cancelable context
dir.ListDirRecursiveContext(ctx, func(f fs.File) error {
	_, err := fmt.Println(f.Name())
	return err
}, "*.jpg", "*.jpeg")

// Get all files in dir without limit
files, err := dir.ListDirMax(-1)

// Get the first 100 JPEGs in dir
files, err := dir.ListDirMaxContext(ctx, 100, "*.jpg", "*.jpeg")

Watching the local file system

TODO description

# Packages

fsimpl contains helper functions for implementing a fs.FileSystem.
Package httpfs implements a read only file system for HTTP URLs.
No description provided by the author
No description provided by the author
Package uuiddirs provides functions to split up a UUID into a series of sub-directories so that an unlimited number of UUIDs can be used as directories.
No description provided by the author

# Functions

AllExist returns true if the Exists method of all files returned true.
AsFileReaders converts the passed files to []FileReader.
CleanFilePath returns a File from uri with cleaned path and a file system prefix.
ContainsLocalPath returns true if the passed localPath matches the result from the LocalPath method of any of the files.
ContainsName returns true if the passed filename matches the result from the Name method of any of the files.
ContentHashFuncFrom returns a ContentHashFunc that uses a standard hash.Hash implementation to return the hash sum as hex encoded string.
ContentHashIndex returns the slice index of the first file where the passed hash equals the result from the ContentHashContext method or -1 in case of no match.
CopyFile copies a single file between different file systems.
CopyFileBuf copies a single file between different file systems.
CopyRecursive can copy between files of different file systems.
CurrentWorkingDir returns the current working directory of the process.
ExecutableFile returns a File for the executable that started the current process.
FileContentHash returns the hashFunc result for fileReader.
Filef is a shortcut for File(fmt.Sprintf(format, args...)).
FileInfoToFileCallback converts a File callback function into a FileInfo callback function that is calling the passed fileCallback with the FileInfo.File.
FileNames returns the names of the passed files.
FilePaths returns the FileSystem specific paths the passed files.
FileReadersFromStrings returns FileReaders for the given fileURIs.
FileReaderWithName returns a new FileReader that wraps the passed fileReader, but the Name() method returns the passed name instead of name of the wrapped fileReader.
FilesFromStrings returns Files for the given fileURIs.
FileURLs returns the URLs of the passed files.
GetFileSystem returns a FileSystem for the passed URI.
GetFileSystemByPrefixOrNil returns the file system registered with the passed prefix, or nil if it can't be found.
Glob yields files and wildcard substituting path segments matching a path pattern.
HomeDir returns the home directory of the current user.
IdenticalDirContents returns true if the files in dirA and dirB are identical in size and content.
IdenticalFileContents returns if the passed files have identical content.
IsRegistered returns true if the file system is registered with its prefix.
JoinCleanFilePath returns a File from joined and cleaned uriParts with a file system prefix.
No description provided by the author
LocalPathIndex returns the slice index of the first file where the passed localPath equals the result from the LocalPath method or -1 in case of no match.
MakeTempDir makes and returns a new randomly named sub directory in TempDir().
Move moves and/or renames source to destination.
MustGlob yields files and wildcard substituting path segments matching a path pattern.
MustMakeTempDir makes and returns a new randomly named sub directory in TempDir().
NameIndex returns the slice index of the first file where the passed filename equals the result from the Name method or -1 in case of no match.
NewErrAlreadyExists returns a new ErrAlreadyExists.
NewErrDoesNotExist returns a new ErrDoesNotExist.
NewErrDoesNotExistFileReader returns an ErrDoesNotExist error for a FileReader.
NewErrIsDirectory returns a new ErrIsDirectory.
NewErrIsNotDirectory returns a new ErrIsNotDirectory.
NewErrPathDoesNotExist returns an ErrDoesNotExist error for a file path.
NewErrPermission returns a new ErrPermission.
NewErrUnsupported returns a new ErrUnsupported.
NewFileInfo returns a FileInfo using the data from an io/fs.FileInfo as snapshot of an existing file.
NewFileInfoCache returns a new FileInfoCache with timeout, or nil if timeout is zero.
NewMemFile returns a new MemFile.
No description provided by the author
NewMemFileWriteJSON returns a new MemFile with the input mashalled to JSON as FileData.
NewMemFileWriteXML returns a new MemFile with the input mashalled to XML as FileData.
NewNonExistingFileInfo returns a FileInfo for a potentially non existing file.
NewSingleMemFileSystem creates and registers a new MemFileSystem containing a single MemFile that is returned as a File that can be used to access the file without knowing the file system.
NotExistsIndex returns the slice index of the first FileReader where the Exists method returned false or -1 in case of no match.
ParseRawURI returns a FileSystem for the passed URI and the path component within that file system.
No description provided by the author
ReadAllContext reads all data from r until EOF is reached, another error is returned, or the context got canceled.
ReadAllMemFile returns a new MemFile with the data from ReadAllContext(r) and the passed name.
ReadHeader reads up to maxNumBytes from the beginning of the passed FileReader.
ReadHeaderString reads up to maxNumBytes as string from the beginning of the passed FileReader.
ReadMemFile returns a new MemFile with name and data from fileReader.
ReadMemFileRename returns a new MemFile with the data from fileReader and the passed name.
Register adds a file system or increments its reference count if it is already registered.
RegisteredFileSystems returns the registered file systems sorted by their prefix.
Remove removes all files with fileURIs.
RemoveErrDoesNotExist returns nil if err wraps os.ErrNotExist, else err will be returned unchanged.
RemoveFile removes a single file.
RemoveFiles removes all files.
SameFile returns if a and b describe the same file or directory.
ServeFileHTTP serves the passed file with a Content-Type header via HTTP.
ServeFileHTTPHandler returns a http.Handler that serves the passed file with a Content-Type header via HTTP.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
SourceFile returns the file of the caller of the current function.
TempDir returns the temp directory of the operating system.
TempFile returns a randomly named File with an optional extension in the temp directory of the operating system.
TempFileCopy copies the provided source file to the temp directory of the operating system using a random filename with the extension of the source file.
Unregister a file system decrements its reference count and removes it when the reference count reaches 0.
UnzipToMemFiles unzips the passed zipFile as MemFiles.
WriteAllContext writes all data wo the to w with a cancelable context.

# Constants

ErrFileSystemClosed is returned after a file system Close method was called.
ErrInvalidFileSystem indicates an invalid file system.
No description provided by the author
No description provided by the author
ErrReadOnlyFileSystem is returned when a file system doesn't support writes.
No description provided by the author
No description provided by the author
ErrWriteOnlyFileSystem is returned when a file system doesn't support reads.
InvalidFile is a file with an empty path and thus invalid.
LocalPrefix is the prefix of the LocalFileSystem.
No description provided by the author
Separator used in LocalFileSystem paths.

# Variables

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
DefaultContentHash configures the default content hash function used by methods like File.ContentHash and FileReader.ContentHash.
ErrEmptyPath indications an empty file path.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Local is the local file system.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Structs

ErrAlreadyExists is returned when a file already exists.
ErrDoesNotExist is returned when a file does not exist and wraps os.ErrNotExist.
ErrIsDirectory is returned when an operation is not possible because a file is a directory.
ErrIsNotDirectory is returned when an operation is not possible because a file is not a directory.
ErrPermission is returned when an operation lacks permissions on a file.
No description provided by the author
FileInfo is a snapshot of a file's stat information.
FileInfoCache is a cache with timeout for FileInfo data.
LocalFileSystem implements FileSystem for the local file system.
MemFile implements FileReader with a filename and an in memory byte slice.
MemFileSystem is a fully featured thread-safe file system living in random access memory.
ReadOnlyBase implements the writing methods of the FileSystem interface to do nothing and return ErrReadOnlyFileSystem.
StdDirEntry implements the io/fs.DirEntry interface from the standard library for a File.
StdFS implements the io/fs.FS interface of the standard library for a File.

# Interfaces

No description provided by the author
No description provided by the author
CopyFileSystem can be implemented by file systems that have native file copying functionality.
No description provided by the author
No description provided by the author
FileSystem is an interface that has to be implemented for a file system to be accessable via this package.
No description provided by the author
No description provided by the author
No description provided by the author
Logger is an interface that can be implemented to log errors.
No description provided by the author
MoveFileSystem can be implemented by file systems that have native file moving functionality.
No description provided by the author
No description provided by the author
ReadSeekCloser combines the interfaces io.Reader io.ReaderAt io.Seeker io.Closer.
ReadWriteSeekCloser combines the interfaces io.Reader io.ReaderAt io.Writer io.WriterAt io.Seeker io.Closer.
RenameFileSystem can be implemented by file systems that have native file renaming functionality.
No description provided by the author
No description provided by the author
No description provided by the author
VolumeNameFileSystem should be implemented by file systems that have volume names.
WatchFileSystem can be implemented by file systems that have file watching functionality.
No description provided by the author
WriteSeekCloser combines the interfaces io.Writer io.WriterAt io.Seeker io.Closer.

# Type aliases

ContentHashFunc is used tot return the string representation of a content hash by reading from an io.Reader until io.EOF or the context is cancelled.
Event reported for watched files.
File is a local file system path or a complete URI.
InvalidFileSystem is a file system where all operations are invalid.
LoggerFunc implements Logger as higher order function.
Permissions for a file, follows the Unix/os.FileMode bit schema.
No description provided by the author
SentinelError is used for const sentinel errors.
No description provided by the author