Examples
A function that takes fs.FS works with any of these. That is the whole point of the package: the code does not know or care where the bytes come from.
func render(fsys fs.FS, name string) (string, error) {
b, err := fs.ReadFile(fsys, name)
return string(b), err
}
render(os.DirFS("./static"), "site.css") // disk
render(assets, "static/site.css") // embed.FS
render(zipReader, "static/site.css") // zip archive
render(mem, "static/site.css") // fstest.MapFSbody { color: red }WalkDir visits every entry depth-first. Returning SkipDir from a directory skips its contents; SkipAll stops the whole walk without producing an error.
err := fs.WalkDir(assets, ".", func(p string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
fmt.Printf("%-22s dir=%v\n", p, d.IsDir())
return nil
}). dir=true
static dir=true
static/greeting.txt dir=false
static/site.css dir=falseSub re-roots a filesystem so callers see shorter paths. Handy when an embed keeps its directory prefix but the code should not have to.
sub, err := fs.Sub(assets, "static")
if err != nil {
log.Fatal(err)
}
names, _ := fs.Glob(sub, "*.txt")
fmt.Println(names)[greeting.txt]fstest.MapFS is a filesystem made from a map. It turns a test that needed a temp directory into one that needs nothing.
mem := fstest.MapFS{
"a/one.txt": {Data: []byte("1")},
"a/two.txt": {Data: []byte("2")},
}
got, _ := fs.ReadFile(mem, "a/two.txt")
fmt.Println("read:", string(got))
entries, _ := fs.ReadDir(mem, "a")
for _, e := range entries {
fmt.Println("entry:", e.Name())
}read: 2
entry: one.txt
entry: two.txt| Function | Description |
|---|---|
type FS interface | One method, Open(name string) (File, error). Everything else in the package is built on it. |
type File interface | Stat() (FileInfo, error), Read([]byte) (int, error), and Close() error. |
type ReadDirFS interface | An FS that can also list a directory, via ReadDir(name string) ([]DirEntry, error). |
type ReadFileFS interface | An FS that can read a whole file in one call, which avoids Open and Close. |
type StatFS interface | An FS that can Stat without opening the file. |
type SubFS interface | An FS that can return a subtree directly instead of being wrapped. |
type GlobFS interface | An FS with its own Glob, usually because it can match faster than walking. |
type DirEntry interface | Name, IsDir, Type, and Info. Cheaper than FileInfo because Info is deferred. |
type FileInfo interface | Name, Size, Mode, ModTime, IsDir, and Sys. |
ReadFile(fsys FS, name string) ([]byte, error) fs.ReadFile(assets, "static/site.css") | Reads a whole file. Uses ReadFileFS when the filesystem provides it. |
ReadDir(fsys FS, name string) ([]DirEntry, error) | Lists a directory, sorted by filename. |
Stat(fsys FS, name string) (FileInfo, error) | Metadata for one entry. |
Sub(fsys FS, dir string) (FS, error) sub, _ := fs.Sub(assets, "static") | A filesystem rooted at dir, so callers see shorter paths. |
An | |
Glob(fsys FS, pattern string) ([]string, error) | Every name matching the pattern, sorted. |
WalkDir(fsys FS, root string, fn WalkDirFunc) error | Walks a tree depth-first in lexical order. |
The callback receives an error argument for entries that could not be read. Ignoring it means a permission failure silently truncates the walk. | |
SkipDir | Returned from a WalkDirFunc to skip the current directory's contents. |
SkipAll | Returned from a WalkDirFunc to stop the walk with no error. |
ValidPath(name string) bool | Reports whether a name is valid for an FS: slash-separated, unrooted, no . or .. elements. |
An | |
FileMode | The same mode bits as os.FileMode, which is an alias for this type. |
ErrNotExist, ErrExist, ErrPermission, ErrClosed | The sentinel errors, matched with errors.Is. |