Source File
fs.go
Belonging Package
io/fs
// Copyright 2020 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// Package fs defines basic interfaces to a file system.// A file system can be provided by the host operating system// but also by other packages.package fsimport ()// An FS provides access to a hierarchical file system.//// The FS interface is the minimum implementation required of the file system.// A file system may implement additional interfaces,// such as ReadFileFS, to provide additional or optimized functionality.type FS interface {// Open opens the named file.//// When Open returns an error, it should be of type *PathError// with the Op field set to "open", the Path field set to name,// and the Err field describing the problem.//// Open should reject attempts to open names that do not satisfy// ValidPath(name), returning a *PathError with Err set to// ErrInvalid or ErrNotExist.Open(name string) (File, error)}// ValidPath reports whether the given path name// is valid for use in a call to Open.//// Path names passed to open are UTF-8-encoded,// unrooted, slash-separated sequences of path elements, like “x/y/z”.// Path names must not contain an element that is “.” or “..” or the empty string,// except for the special case that the root directory is named “.”.// Paths must not start or end with a slash: “/x” and “x/” are invalid.//// Note that paths are slash-separated on all systems, even Windows.// Paths containing other characters such as backslash and colon// are accepted as valid, but those characters must never be// interpreted by an FS implementation as path element separators.func ( string) bool {if !utf8.ValidString() {return false}if == "." {// special casereturn true}// Iterate over elements in name, checking each.for {:= 0for < len() && [] != '/' {++}:= [:]if == "" || == "." || == ".." {return false}if == len() {return true // reached clean ending}= [+1:]}}// A File provides access to a single file.// The File interface is the minimum implementation required of the file.// A file may implement additional interfaces, such as// ReadDirFile, ReaderAt, or Seeker, to provide additional or optimized functionality.type File interface {Stat() (FileInfo, error)Read([]byte) (int, error)Close() error}// A DirEntry is an entry read from a directory// (using the ReadDir function or a ReadDirFile's ReadDir method).type DirEntry interface {// Name returns the name of the file (or subdirectory) described by the entry.// This name is only the final element of the path (the base name), not the entire path.// For example, Name would return "hello.go" not "/home/gopher/hello.go".Name() string// IsDir reports whether the entry describes a directory.IsDir() bool// Type returns the type bits for the entry.// The type bits are a subset of the usual FileMode bits, those returned by the FileMode.Type method.Type() FileMode// Info returns the FileInfo for the file or subdirectory described by the entry.// The returned FileInfo may be from the time of the original directory read// or from the time of the call to Info. If the file has been removed or renamed// since the directory read, Info may return an error satisfying errors.Is(err, ErrNotExist).// If the entry denotes a symbolic link, Info reports the information about the link itself,// not the link's target.Info() (FileInfo, error)}// A ReadDirFile is a directory file whose entries can be read with the ReadDir method.// Every directory file should implement this interface.// (It is permissible for any file to implement this interface,// but if so ReadDir should return an error for non-directories.)type ReadDirFile interface {File// ReadDir reads the contents of the directory and returns// a slice of up to n DirEntry values in directory order.// Subsequent calls on the same file will yield further DirEntry values.//// If n > 0, ReadDir returns at most n DirEntry structures.// In this case, if ReadDir returns an empty slice, it will return// a non-nil error explaining why.// At the end of a directory, the error is io.EOF.//// If n <= 0, ReadDir returns all the DirEntry values from the directory// in a single slice. In this case, if ReadDir succeeds (reads all the way// to the end of the directory), it returns the slice and a nil error.// If it encounters an error before the end of the directory,// ReadDir returns the DirEntry list read until that point and a non-nil error.ReadDir(n int) ([]DirEntry, error)}// Generic file system errors.// Errors returned by file systems can be tested against these errors// using errors.Is.var (ErrInvalid = errInvalid() // "invalid argument"ErrPermission = errPermission() // "permission denied"ErrExist = errExist() // "file already exists"ErrNotExist = errNotExist() // "file does not exist"ErrClosed = errClosed() // "file already closed")func () error { return oserror.ErrInvalid }func () error { return oserror.ErrPermission }func () error { return oserror.ErrExist }func () error { return oserror.ErrNotExist }func () error { return oserror.ErrClosed }// A FileInfo describes a file and is returned by Stat.type FileInfo interface {Name() string // base name of the fileSize() int64 // length in bytes for regular files; system-dependent for othersMode() FileMode // file mode bitsModTime() time.Time // modification timeIsDir() bool // abbreviation for Mode().IsDir()Sys() interface{} // underlying data source (can return nil)}// A FileMode represents a file's mode and permission bits.// The bits have the same definition on all systems, so that// information about files can be moved from one system// to another portably. Not all bits apply to all systems.// The only required bit is ModeDir for directories.type FileMode uint32// The defined file mode bits are the most significant bits of the FileMode.// The nine least-significant bits are the standard Unix rwxrwxrwx permissions.// The values of these bits should be considered part of the public API and// may be used in wire protocols or disk representations: they must not be// changed, although new bits might be added.const (// The single letters are the abbreviations// used by the String method's formatting.ModeDir FileMode = 1 << (32 - 1 - iota) // d: is a directoryModeAppend // a: append-onlyModeExclusive // l: exclusive useModeTemporary // T: temporary file; Plan 9 onlyModeSymlink // L: symbolic linkModeDevice // D: device fileModeNamedPipe // p: named pipe (FIFO)ModeSocket // S: Unix domain socketModeSetuid // u: setuidModeSetgid // g: setgidModeCharDevice // c: Unix character device, when ModeDevice is setModeSticky // t: stickyModeIrregular // ?: non-regular file; nothing else is known about this file// Mask for the type bits. For regular files, none will be set.ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice | ModeCharDevice | ModeIrregularModePerm FileMode = 0777 // Unix permission bits)func ( FileMode) () string {const = "dalTLDpSugct?"var [32]byte // Mode is uint32.:= 0for , := range {if &(1<<uint(32-1-)) != 0 {[] = byte()++}}if == 0 {[] = '-'++}const = "rwxrwxrwx"for , := range {if &(1<<uint(9-1-)) != 0 {[] = byte()} else {[] = '-'}++}return string([:])}// IsDir reports whether m describes a directory.// That is, it tests for the ModeDir bit being set in m.func ( FileMode) () bool {return &ModeDir != 0}// IsRegular reports whether m describes a regular file.// That is, it tests that no mode type bits are set.func ( FileMode) () bool {return &ModeType == 0}// Perm returns the Unix permission bits in m (m & ModePerm).func ( FileMode) () FileMode {return & ModePerm}// Type returns type bits in m (m & ModeType).func ( FileMode) () FileMode {return & ModeType}// PathError records an error and the operation and file path that caused it.type PathError struct {Op stringPath stringErr error}func ( *PathError) () string { return .Op + " " + .Path + ": " + .Err.Error() }func ( *PathError) () error { return .Err }// Timeout reports whether this error represents a timeout.func ( *PathError) () bool {, := .Err.(interface{ () bool })return && .()}