概观
Afero 是一个文件系统框架,提供与任何文件系统的简单,统一和通用的交互 API。作为提供接口,类型和方法的抽象层,Afero 具有非常干净的接口和简单的设计,没有不必要的构造函数或初始化方法。
Afero 也是一个库,提供一组可互操作的后端文件系统,轻松地使用。同时保留 os 和 ioutil 包的所有功能和优点.
Afero 比单独使用 os 包提供了显着的改进,最显着的是能够在不依赖磁盘的情况下,创建模拟和测试文件系统.
它考虑到了,您想使用 OS 包的任何情况,因为它提供了额外的抽象,使得在测试期间可以轻松使用内存支持的文件系统。它还增加了对 http 文件系统的支持,以实现完全的互操作性.
Afero 特性
- 用于访问各种文件系统的唯一的一致 API
- 各种文件系统类型之间的互操作
- 一组接口,用于鼓励,和实现后端之间的互操作性
- 跨平台内存支持的文件原子系统
- 通过组合多个文件系统,来支持一个组合(联合)文件系统
- 修改现有文件系统的专用后端(只读,Regexp 过滤)
- 一组从 io,ioutil 和 hugo 移植到 afero 的实用函数
使用 Afero
Afero 易于使用,且简单明了.
您可以使用 Afero 的几种不同方式:
- 单独使用接口,来定义您自己的文件系统.
- 包装为 OS 包.
- 为应用程序的不同部分,定义不同的文件系统.
- 在测试时,使用 Afero 模拟文件系统
第 1 步:安装 Afero
首先使用 go get 安装最新版本的库.
1
|
go get github.com/spf13/afero
|
接下来在您的应用程序中,包含 Afero.
1
|
import "github.com/spf13/afero"
|
第 2 步:声明后端
首先定义一个包级变量,并将其设置为指向文件系统的指针.
1
2
3
4
5
|
var AppFs = afero.NewMemMapFs()
or
var AppFs = afero.NewOsFs()
|
重要的是要注意,如果重复调用,您将使用一个全新的隔离文件系统。在 OsFs 的情况下,它仍将使用相同的底层文件系统,但会降低根据需要放入其他文件系统的能力.
第 3 步:像操作系统包一样使用它
在整个应用程序中,使用您通常会使用的任何功能和方法.
所以,如果我以前的应用有:
我们将其替换为:
AppFs是我们上面定义的变量.
所有可用功能的列表
文件系统方法可用:
1
2
3
4
5
6
7
8
9
10
11
12
|
Chmod(name string, mode os.FileMode) : error
Chtimes(name string, atime time.Time, mtime time.Time) : error
Create(name string) : File, error
Mkdir(name string, perm os.FileMode) : error
MkdirAll(path string, perm os.FileMode) : error
Name() : string
Open(name string) : File, error
OpenFile(name string, flag int, perm os.FileMode) : File, error
Remove(name string) : error
RemoveAll(path string) : error
Rename(oldname, newname string) : error
Stat(name string) : os.FileInfo, error
|
文件接口和方法可用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
io.Closer
io.Reader
io.ReaderAt
io.Seeker
io.Writer
io.WriterAt
Name() : string
Readdir(count int) : []os.FileInfo, error
Readdirnames(n int) : []string, error
Stat() : os.FileInfo, error
Sync() : error
Truncate(size int64) : error
WriteString(s string) : ret int, err error
|
在某些应用程序中,定义一个只导出文件系统变量的新包,就可以从任何地方轻松访问。
使用 Afero 的实用功能
Afero 提供了一组函数,使其更易于使用底层文件系统。这些函数主要来自 io&ioutil,其中一些是为 Hugo 开发的.
afero 实用程序,支持所有 afero 兼容的后端.
实用程序列表包括:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
DirExists(path string) (bool, error)
Exists(path string) (bool, error)
FileContainsBytes(filename string, subslice []byte) (bool, error)
GetTempDir(subPath string) string
IsDir(path string) (bool, error)
IsEmpty(path string) (bool, error)
ReadDir(dirname string) ([]os.FileInfo, error)
ReadFile(filename string) ([]byte, error)
SafeWriteReader(path string, r io.Reader) (err error)
TempDir(dir, prefix string) (name string, err error)
TempFile(dir, prefix string) (f File, err error)
Walk(root string, walkFn filepath.WalkFunc) error
WriteFile(filename string, data []byte, perm os.FileMode) error
WriteReader(path string, r io.Reader) (err error)
|
有关完整列表,请参阅Afero 的 GoDoc
这里是有两种不同的使用方法。
-
您可以直接调用它们,每个函数的第一个参数将是文件系统,或者
-
您可以声明一个新Afero,一种自定义类型,用于将这些函数绑定到,给定文件系统的方法.
直接调用实用程序
1
2
|
fs := new(afero.MemMapFs)
f, err := afero.TempFile(fs,"", "ioutil-test")
|
通过 Afero 调用
1
2
3
|
fs := afero.NewMemMapFs()
afs := &afero.Afero{Fs: fs}
f, err := afs.TempFile("", "ioutil-test")
|
使用 Afero 进行测试
使用模拟文件系统进行测试有很大好处。每次初始化时,它都处于完全空白状态,无论操作系统如何,都可以轻松重现。您可以创建重要内容文件,文件访问速度快,同时还可以避免,删除临时文件,Windows 文件锁定等所有烦人的问题。MemMapFs 后端非常适合测试.
- 比在磁盘上执行 I/O 操作快得多
- 避免安全和权限问题
- 更多的控制。‘rm -rf /‘将充满信心
- 测试设置要容易得多
- 无需进行测试清理
实现此目的的一种方法是定义如上所述的变量。在您的应用程序测试期间,这将被设置为afero.NewOsFs(),当然您也可以设为 afero.NewMemMapFs().
每个测试都初始化一个空白的平板内存后端并不少见。要做到这一点, 在我应用程序代码中适当的地方,定义appFS = afero.NewOsFs()。此方法可确保测试与顺序无关,并且没有依赖于早期测试留下的状态.
然后在我的测试中,我会为每个测试初始化一个新的 MemMapF:
1
2
3
4
5
6
7
8
9
10
11
12
|
func TestExist(t *testing.T) {
appFS := afero.NewMemMapFs()
// 创建 test 文件 和 目录
appFS.MkdirAll("src/a", 0755)
afero.WriteFile(appFS, "src/a/b", []byte("file b"), 0644)
afero.WriteFile(appFS, "src/c", []byte("file c"), 0644)
name := "src/c"
_, err := appFS.Stat(name)
if os.IsNotExist(err) {
t.Errorf("file \"%s\" does not exist.\n", name)
}
}
|
可用的后端
原生操作系统
OsFs
第一个是围绕原生 OS 调用的包装器。将它变得非常容易使用,因为所有调用都与现有的 OS 调用相同。它还使您的代码在操作系统,与根据需要使用模拟文件系统时,变得轻松,甚至无聊^_^。
1
2
|
appfs := afero.NewOsFs()
appfs.MkdirAll("src/a", 0755))
|
内存支持存储
MemMapFs
Afero 还提供完全原子内存支持的文件系统,非常适合用于模拟,并在不需要保持时,加速不必要的磁盘。它是完全并发的,可以安全地在 go 协程中使用.
1
2
|
mm := afero.NewMemMapFs()
mm.MkdirAll("src/a", 0755))
|
InMemoryFile
作为 MemMapFs 的一部分,Afero 还提供原子的,完全并发的内存支持文件实现.这可以轻松地在其他内存支持的文件系统中使用.计划是使用 InMemoryFile 添加基数树内存存储文件系统.
网络接口
SftpFs
Afero 对安全文件传输协议(sftp)有实验性的支持。可用于加密通道上执行文件操作.
过滤后端
BasePathFs
BasePathF 将所有操作限制在 Fs 内的给定路径。在调用这个源 Fs 之前, Fs 操作的给定文件名,会以基本路径为前缀.
1
|
bp := afero.NewBasePathFs(afero.NewOsFs(), "/base/path")
|
ReadOnlyFs
源 Fs 周围的薄包装器,提供只读的.
1
2
3
|
fs := afero.NewReadOnlyFs(afero.NewOsFs())
_, err := fs.Create("/file.txt")
// err = syscall.EPERM
|
RegexpFs
对文件名进行过滤后的,任何与传递的正则表达式不匹配的文件,都将被视为不存在。将不会创建与提供的正则表达式不匹配的文件。目录不过滤.
1
2
3
|
fs := afero.NewRegexpFs(afero.NewMemMapFs(), regexp.MustCompile(`\.txt$`))
_, err := fs.Create("/file.html")
// err = syscall.ENOENT
|
HttpFs
Afero 提供了一个 http 兼容的后端,可以包装任何现有的后端.
Http 包需要稍微特定的 Open 版本,它返回一个 http.File 类型.
Afero 提供满足此要求的 httpFs 文件系统。任何 Afero FileSystem 都可以用作 httpFs。
1
2
3
|
httpFs := afero.NewHttpFs(<ExistingFS>)
fileserver := http.FileServer(httpFs.Dir(<PATH>)))
http.Handle("/", fileserver)
|
复合后端
Afero 提供合成两个文件系统(或更多),作为单个文件系统的能力.
CacheOnReadFs
CacheOnReadFs 将懒洋洋地将任何访问过的文件,从基础层-base复制到覆盖层-overlay中。后续读取将直接从覆盖层中提取,允许缓存持续时间内,请求在覆盖层中创建的缓存。
如果基本文件系统是可写的,则对文件的任何更改,将首先对基础层进行,然后对覆盖层进行。而打开文件的 Write 调用控制,如Write()或Truncate()则先到覆盖层.
要仅将文件写入覆盖层,可以直接使用覆盖层 Fs(而不是通过联合 Fs).
在给定time.Duration缓存持续时间内,对该层中的文件进行缓存,缓存持续时间为 0 ,意味着"永远",意味着文件将不会从基础层重新请求.
只读的基础层会让覆盖层也是只读的,但是当文件在缓存层中不存在(或过时)时,仍然将文件从基础层复制到覆盖层.
1
2
3
|
base := afero.NewOsFs()
layer := afero.NewMemMapFs()
ufs := afero.NewCacheOnReadFs(base, layer, 100 * time.Second)
|
CopyOnWriteFs()
CopyOnWriteFs 是一个只读的基本文件系统,顶部有一个可写的层.
Read 操作首先查看覆盖层,如果没有找到,将从基础层提供文件服务.
只能在覆盖层中对文件系统进行更改.
任何仅在基础中找到的文件的修改,都会在修改(包括打开可写的文件)之前,将文件复制到覆盖层.
目前不允许删除和重命名,仅存在于基础层中的文件。如果文件在基础层和覆盖层中存在,则仅能删除/重命名覆盖层.
1
2
3
4
5
6
7
|
base := afero.NewOsFs()
roBase := afero.NewReadOnlyFs(base)
ufs := afero.NewCopyOnWriteFs(roBase, afero.NewMemMapFs())
fh, _ = ufs.Create("/home/test/file2.txt")
fh.WriteString("This is a test")
fh.Close()
|
在此示例中,所有写入操作仅发生在内存(MemMapFs)中, 基本文件系统(OsFs)保持不变.
库
常量
1
2
|
const BADFD = syscall.EBADFD
const FilePathSeparator = string(filepath.Separator)
|
os.Separator定义的文件路径分隔符。
变量
1
2
3
4
5
6
7
8
9
10
11
|
var(
var (
ErrFileClosed = errors.New("File is closed")
ErrOutOfRange = errors.New("Out of range")
ErrTooLarge = errors.New("Too large")
ErrFileNotFound = os.ErrNotExist
ErrFileExists = os.ErrExist
ErrDestinationExists = os.ErrExist
)
var ErrNoReadlink = errors.New("readlink not supported")
|
如果文件系统不直接或通过其委派的文件系统不支持readlink操作,则ErrNoReadlink是将包装在os.Path中的错误。如对LinkReader接口的支持所示。
1
|
var ErrNoSymlink = errors.New("symlink not supported")
|
如果文件系统不直接或通过其委派的文件系统不支持Symlink,则ErrNoSymlink是将包装在os.LinkError中的错误。如对Linker接口的支持所示。
func DirExists
1
|
func DirExists(fs Fs, path string) (bool, error)
|
DirExists检查路径是否存在并且是目录。
func Exists
1
|
func Exists(fs Fs, path string) (bool, error)
|
检查文件或目录是否存在。
func FileContainsAnyBytes
1
|
func FileContainsAnyBytes(fs Fs, filename string, subslices [][]byte) (bool, error)
|
检查文件是否包含任何指定的字节片。
func FileContainsBytes
1
|
func FileContainsBytes(fs Fs, filename string, subslice []byte) (bool, error)
|
检查文件是否包含指定的字节片。
func FullBaseFsPath
1
|
func FullBaseFsPath(basePathFs *BasePathFs, relativePath string) string
|
func GetTempDir
1
|
func GetTempDir(fs Fs, subPath string) string
|
如果subPath不为空,则GetTempDir返回带有尾斜杠的默认temp目录,它将以777 rwx rwx rwx模式递归创建
func Glob
1
|
func Glob(fs Fs, pattern string) (matches []string, err error)
|
Glob返回所有匹配模式的文件的名称,如果没有匹配的文件,则返回nil。模式的语法与Match中的语法相同。该模式可以描述分层名称,例如/usr/*/bin/ed(假设分隔符为’/’)。
Glob会忽略文件系统错误,例如读取目录的I/O错误。模式格式错误时,唯一可能返回的错误是ErrBadPattern。
改编自(http://golang.org/pkg/path/filepath),并使用了该软件包中的多个内置插件。
func IsDir
1
|
func IsDir(fs Fs, path string) (bool, error)
|
IsDir检查给定路径是否为目录。
func IsEmpty
1
|
func IsEmpty(fs Fs, path string) (bool, error)
|
IsEmpty检查给定的文件或目录是否为空。
func NeuterAccents
1
|
func NeuterAccents(s string) string
|
将带有重音符号的字符转换为简单形式。
func ReadAll
1
|
func ReadAll(r io.Reader) ([]byte, error)
|
ReadAll从r读取直到出现错误或EOF,然后返回读取的数据。成功调用将返回err == nil,而不是err == EOF。因为ReadAll被定义为从src读取直到EOF,所以它不会将读取的EOF视为要报告的错误。
func ReadDir
1
|
func ReadDir(fs Fs, dirname string) ([]os.FileInfo, error)
|
func ReadFile
1
|
func ReadFile(fs Fs, filename string) ([]byte, error)
|
func SafeWriteReader
1
|
func SafeWriteReader(fs Fs, path string, r io.Reader) (err error)
|
func TempDir
1
|
func TempDir(fs Fs, dir, prefix string) (name string, err error)
|
func UnicodeSanitize
1
|
func UnicodeSanitize(s string) string
|
重写字符串以删除非标准路径字符
func Walk
1
|
func Walk(fs Fs, root string, walkFn filepath.WalkFunc) error
|
func WriteFile
1
|
func WriteFile(fs Fs, filename string, data []byte, perm os.FileMode) error
|
func WriteReader
1
|
func WriteReader(fs Fs, path string, r io.Reader) (err error)
|
type Afero
1
2
3
|
type Afero struct {
Fs
}
|
func (Afero) DirExists
1
|
func (a Afero) DirExists(path string) (bool, error)
|
func (Afero) Exists
1
|
func (a Afero) Exists(path string) (bool, error)
|
func (Afero) FileContainsAnyBytes
1
|
func (a Afero) FileContainsAnyBytes(filename string, subslices [][]byte) (bool, error)
|
func (Afero) FileContainsBytes
1
|
func (a Afero) FileContainsBytes(filename string, subslice []byte) (bool, error)
|
func (Afero) GetTempDir
1
|
func (a Afero) GetTempDir(subPath string) string
|
func (Afero) IsDir
1
|
func (a Afero) IsDir(path string) (bool, error)
|
func (Afero) IsEmpty
1
|
func (a Afero) IsEmpty(path string) (bool, error)
|
func (Afero) ReadDir
1
|
func (a Afero) ReadDir(dirname string) ([]os.FileInfo, error)
|
ReadDir读取以目录名命名的目录,并返回已排序目录条目的列表。
func (Afero) ReadFile
1
|
func (a Afero) ReadFile(filename string) ([]byte, error)
|
ReadFile读取以文件名命名的文件并返回内容。成功调用将返回err == nil,而不是err == EOF。由于ReadFile读取整个文件,因此不会将Read中的EOF视为要报告的错误。
func (Afero) SafeWriteReader
1
|
func (a Afero) SafeWriteReader(path string, r io.Reader) (err error)
|
与WriteReader相同,但检查文件/目录是否已存在。
func (Afero) TempDir
1
|
func (a Afero) TempDir(dir, prefix string) (name string, err error)
|
TempDir在目录dir中创建一个以前缀开头的名称的新临时目录,并返回新目录的路径。如果dir是空字符串,则TempDir使用默认目录存储临时文件(请参见os.TempDir)。同时调用TempDir的多个程序将不会选择同一目录。不再需要该目录时,调用方有责任删除它。
func (Afero) TempFile
1
|
func (a Afero) TempFile(dir, pattern string) (f File, err error)
|
TempFile在目录dir中创建一个新的临时文件,打开该文件以进行读取和写入,然后返回生成的*os.File。通过采用模式并在末尾添加随机字符串来生成文件名。如果pattern包含“”,则随机字符串将替换最后的“”。如果dir是空字符串,则TempFile使用默认目录存储临时文件(请参见os.TempDir)。同时调用TempFile的多个程序将不会选择同一文件。调用者可以使用f.Name()查找文件的路径名。不再需要该文件时,调用方有责任删除它。
func (Afero) Walk
1
|
func (a Afero) Walk(root string, walkFn filepath.WalkFunc) error
|
func (Afero) WriteFile
1
|
func (a Afero) WriteFile(filename string, data []byte, perm os.FileMode) error
|
WriteFile将数据写入以文件名命名的文件。如果该文件不存在,则WriteFile使用权限perm创建它;否则WriteFile会在写入之前将其截断。
func (Afero) WriteReader
1
|
func (a Afero) WriteReader(path string, r io.Reader) (err error)
|
采取读者和路径并撰写内容
type BasePathFile
1
2
3
4
|
type BasePathFile struct {
File
// contains filtered or unexported fields
}
|
func (*BasePathFile) Name
1
|
func (f *BasePathFile) Name() string
|
type BasePathFs
1
2
3
|
type BasePathFs struct {
// contains filtered or unexported fields
}
|
BasePathFs将所有操作限制为Fs中的给定路径。在调用基本F之前,此F上的操作给定的文件名将带有基本路径。该基本路径之外的任何文件名(在filepath.Clean()之后)将被视为不存在的文件。
请注意,它不会清除返回时的错误消息,因此您可能会揭示错误的真实路径。
func (*BasePathFs) Chmod
1
|
FUNC度(b* BasePathFs)CHMOD(名称字符串,模式OS。的FileMode)(ERR 出错)
|
func (*BasePathFs) Chtimes
1
|
func (b *BasePathFs) Chtimes(name string, atime, mtime time.Time) (err error)
|
func (*BasePathFs) Create
1
|
func (b *BasePathFs) Create(name string) (f File, err error)
|
func (*BasePathFs) LstatIfPossible
1
|
func (b *BasePathFs) LstatIfPossible(name string) (os.FileInfo, bool, error)
|
func (*BasePathFs) Mkdir
1
|
func (b *BasePathFs) Mkdir(name string, mode os.FileMode) (err error)
|
func (*BasePathFs) MkdirAll
1
|
func (b *BasePathFs) MkdirAll(name string, mode os.FileMode) (err error)
|
func (*BasePathFs) Name
1
|
func (b *BasePathFs) Name() string
|
func (*BasePathFs) Open
1
|
func (b *BasePathFs) Open(name string) (f File, err error)
|
func (*BasePathFs) OpenFile
1
|
func (b *BasePathFs) OpenFile(name string, flag int, mode os.FileMode) (f File, err error)
|
func (*BasePathFs) ReadlinkIfPossible
1
|
func (b *BasePathFs) ReadlinkIfPossible(name string) (string, error)
|
func (*BasePathFs) RealPath
1
|
func (b *BasePathFs) RealPath(name string) (path string, err error)
|
在基本路径之外的文件上,它返回给定的文件名和错误,否则给定的文件带有基本路径
func (*BasePathFs) Remove
1
|
func (b *BasePathFs) Remove(name string) (err error)
|
func (*BasePathFs) RemoveAll
1
|
func (b *BasePathFs) RemoveAll(name string) (err error)
|
func (*BasePathFs) Rename
1
|
func (b *BasePathFs) Rename(oldname, newname string) (err error)
|
func (*BasePathFs) Stat
1
|
func (b *BasePathFs) Stat(name string) (fi os.FileInfo, err error)
|
func (*BasePathFs) SymlinkIfPossible
1
|
func (b *BasePathFs) SymlinkIfPossible(oldname, newname string) error
|
type CacheOnReadFs
1
2
3
|
type CacheOnReadFs struct {
// contains filtered or unexported fields
}
|
如果缓存持续时间为0,则缓存时间将不受限制,即,一旦文件位于层中,就永远不会再为该文件读取基址。
对于大于0的缓存时间,将检查文件的修改时间。请注意,许多文件系统实现只为时间戳允许分辨率为一秒…或作为os.Chtimes()的godoc声明:“底层文件系统可能会截断值或将值舍入为不太精确的时间单位。”
此缓存联合将首先将所有写调用也转发到基本文件系统。为了防止写入基本Fs,请将其包装在只读过滤器中-注意:这还将使叠加层为只读,要在叠加层中写入文件,请直接使用叠加层Fs,而不是通过并集Fs。
func (*CacheOnReadFs) Chmod
1
|
func (u *CacheOnReadFs) Chmod(name string, mode os.FileMode) error
|
func (*CacheOnReadFs) Chtimes
1
|
func (u *CacheOnReadFs) Chtimes(name string, atime, mtime time.Time) error
|
func (*CacheOnReadFs) Create
1
|
func (u *CacheOnReadFs) Create(name string) (File, error)
|
func (*CacheOnReadFs) Mkdir
1
|
func (u *CacheOnReadFs) Mkdir(name string, perm os.FileMode) error
|
func (*CacheOnReadFs) MkdirAll
1
|
func (u *CacheOnReadFs) MkdirAll(name string, perm os.FileMode) error
|
func (*CacheOnReadFs) Name
1
|
func (u *CacheOnReadFs) Name() string
|
func (*CacheOnReadFs) Open
1
|
func (u *CacheOnReadFs) Open(name string) (File, error)
|
func (*CacheOnReadFs) OpenFile
1
|
func (u *CacheOnReadFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
|
func (*CacheOnReadFs) Remove
1
|
func (u *CacheOnReadFs) Remove(name string) error
|
func (*CacheOnReadFs) RemoveAll
1
|
func (u *CacheOnReadFs) RemoveAll(name string) error
|
func (*CacheOnReadFs) Rename
1
|
func (u *CacheOnReadFs) Rename(oldname, newname string) error
|
func (*CacheOnReadFs) Stat
1
|
func (u *CacheOnReadFs) Stat(name string) (os.FileInfo, error)
|
type CopyOnWriteFs
1
2
3
|
type CopyOnWriteFs struct {
// contains filtered or unexported fields
}
|
CopyOnWriteFs是联合文件系统:只读的基本文件系统,其顶部可能是可写层。只能在叠加层中对文件系统进行更改:更改基本层中不存在于叠加层中的现有文件会将文件复制到叠加层中(“更改”还包括对例如Chtimes()和Chmod())。
当前仅通过Open()而不是OpenFile()支持读取目录。
func (*CopyOnWriteFs) Chmod
1
|
func (u *CopyOnWriteFs) Chmod(name string, mode os.FileMode) error
|
func (*CopyOnWriteFs) Chtimes
1
|
func (u *CopyOnWriteFs) Chtimes(name string, atime, mtime time.Time) error
|
func (*CopyOnWriteFs) Create
1
|
func (u *CopyOnWriteFs) Create(name string) (File, error)
|
func (*CopyOnWriteFs) LstatIfPossible
1
|
func (u *CopyOnWriteFs) LstatIfPossible(name string) (os.FileInfo, bool, error)
|
func (*CopyOnWriteFs) Mkdir
1
|
func (u *CopyOnWriteFs) Mkdir(name string, perm os.FileMode) error
|
func (*CopyOnWriteFs) MkdirAll
1
|
func (u *CopyOnWriteFs) MkdirAll(name string, perm os.FileMode) error
|
func (*CopyOnWriteFs) Name
1
|
func (u *CopyOnWriteFs) Name() string
|
func (*CopyOnWriteFs) Open
1
|
func (u *CopyOnWriteFs) Open(name string) (File, error)
|
此功能处理由联合引起的9种不同可能性,这些可能性是以下原因的交集…
1
2
|
layer: doesn't exist, exists as a file, and exists as a directory
base: doesn't exist, exists as a file, and exists as a directory
|
func (*CopyOnWriteFs) OpenFile
1
|
func (u *CopyOnWriteFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
|
func (*CopyOnWriteFs) ReadlinkIfPossible
1
2
|
func (u *CopyOnWriteFs) ReadlinkIfPossible(name string) (string,
error)
|
func (*CopyOnWriteFs) Remove
1
|
func (u *CopyOnWriteFs) Remove(name string) error
|
不允许删除仅存在于基础层中的文件。如果基础层和覆盖中存在文件,则仅覆盖将被删除。
func (*CopyOnWriteFs) RemoveAll
1
|
func (u *CopyOnWriteFs) RemoveAll(name string) error
|
func (*CopyOnWriteFs) Rename
1
|
func (u *CopyOnWriteFs) Rename(oldname, newname string) error
|
重命名仅存在于基础层中的文件是不允许的
func (*CopyOnWriteFs) Stat
1
|
func (u *CopyOnWriteFs) Stat(name string) (os.FileInfo, error)
|
func (*CopyOnWriteFs) SymlinkIfPossible
1
2
|
func (u *CopyOnWriteFs) SymlinkIfPossible(oldname, newname string)
error
|
type DirsMerger
1
|
type DirsMerger func(lofi, bofi []os.FileInfo) ([]os.FileInfo, error)
|
DirsMerger是UnionFile将两个目录编织在一起的方式。它从图层和基础中获取FileInfo切片,并返回单个视图。
type File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
type File interface {
io.Closer
io.Reader
io.ReaderAt
io.Seeker
io.Writer
io.WriterAt
Name() string
Readdir(count int) ([]os.FileInfo, error)
Readdirnames(n int) ([]string, error)
Stat() (os.FileInfo, error)
Sync() error
Truncate(size int64) error
WriteString(s string) (ret int, err error)
}
|
文件表示文件系统中的文件。
func TempFile
1
|
func TempFile(fs Fs, dir, pattern string) (f File, err error)
|
type Fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
type Fs interface {
// Create creates a file in the filesystem, returning the file and an
// error, if any happens.
Create(name string) (File, error)
// Mkdir creates a directory in the filesystem, return an error if any
// happens.
Mkdir(name string, perm os.FileMode) error
// MkdirAll creates a directory path and all parents that does not exist
// yet.
MkdirAll(path string, perm os.FileMode) error
// Open opens a file, returning it or an error, if any happens.
Open(name string) (File, error)
// OpenFile opens a file using the given flags and the given mode.
OpenFile(name string, flag int, perm os.FileMode) (File, error)
// Remove removes a file identified by name, returning an error, if any
// happens.
Remove(name string) error
// RemoveAll removes a directory path and any children it contains. It
// does not fail if the path does not exist (return nil).
RemoveAll(path string) error
// Rename renames a file.
Rename(oldname, newname string) error
// Stat returns a FileInfo describing the named file, or an error, if any
// happens.
Stat(name string) (os.FileInfo, error)
// The name of this FileSystem
Name() string
//Chmod changes the mode of the named file to mode.
Chmod(name string, mode os.FileMode) error
//Chtimes changes the access and modification times of the named file
Chtimes(name string, atime time.Time, mtime time.Time) error
}
|
Fs是文件系统接口。
任何模拟或真实文件系统都应实现此接口。
func NewBasePathFs
1
|
func NewBasePathFs(source Fs, path string) Fs
|
func NewCacheOnReadFs
1
|
func NewCacheOnReadFs(base Fs, layer Fs, cacheTime time.Duration) Fs
|
func NewCopyOnWriteFs
1
|
func NewCopyOnWriteFs(base Fs, layer Fs) Fs
|
func NewMemMapFs
func NewOsFs
func NewReadOnlyFs
1
|
func NewReadOnlyFs(source Fs) Fs
|
func NewRegexpFs
1
|
func NewRegexpFs(source Fs, re *regexp.Regexp) Fs
|
type HttpFs
1
2
3
4
|
type HttpFs struct {
// contains filtered or unexported fields
}
|
func NewHttpFs
1
|
func NewHttpFs(source Fs) *HttpFs
|
func (HttpFs) Chmod
1
|
func (h HttpFs) Chmod(name string, mode os.FileMode) error
|
func (HttpFs) Chtimes
1
2
|
func (h HttpFs) Chtimes(name string, atime time.Time, mtime time.
Time) error
|
func (HttpFs) Create
1
|
func (h HttpFs) Create(name string) (File, error)
|
func (HttpFs) Dir
1
|
func (h HttpFs) Dir(s string) *httpDir
|
func (HttpFs) Mkdir
1
|
func (h HttpFs) Mkdir(name string, perm os.FileMode) error
|
func (HttpFs) MkdirAll
1
|
func (h HttpFs) MkdirAll(path string, perm os.FileMode) error
|
func (HttpFs) Name
1
|
func (h HttpFs) Name() string
|
func (HttpFs) Open
1
|
func (h HttpFs) Open(name string) (http.File, error)
|
func (HttpFs) OpenFile
1
2
|
func (h HttpFs) OpenFile(name string, flag int, perm os.FileMode)
(File, error)
|
func (HttpFs) Remove
1
|
func (h HttpFs) Remove(name string) error
|
func (HttpFs) RemoveAll
1
|
func (h HttpFs) RemoveAll(path string) error
|
func (HttpFs) Rename
1
|
func (h HttpFs) Rename(oldname, newname string) error
|
func (HttpFs) Stat
1
|
func (h HttpFs) Stat(name string) (os.FileInfo, error)
|
type LinkReader
1
2
3
|
type LinkReader interface {
ReadlinkIfPossible(name string) (string, error)
}
|
LinkReader是Afero中的可选接口。只能通过文件系统来实现。
type Linker
1
2
3
|
type Linker interface {
SymlinkIfPossible(oldname, newname string) error
}
|
链接器是Afero中的可选接口。只能通过文件系统来实现。如果文件系统本身是os文件系统或委托给os文件系统,或者文件系统另外支持Symlink的文件系统,它将调用Symlink。
type Lstater
1
2
3
|
type Lstater interface {
LstatIfPossible(name string) (os.FileInfo, bool, error)
}
|
Lstater是Afero中的可选接口。只能通过文件系统来实现。如果文件系统iself是或委托给os文件系统,它将调用Lstat。除了FileInfo之外,它还将返回一个布尔值,告知是否调用了Lstat。
type MemMapFs
1
2
3
|
type MemMapFs struct {
// contains filtered or unexported fields
}
|
func (*MemMapFs) Chmod
1
|
func (m *MemMapFs) Chmod(name string, mode os.FileMode) error
|
func (*MemMapFs) Chtimes
1
2
|
func (m *MemMapFs) Chtimes(name string, atime time.Time, mtime time.
Time) error
|
func (*MemMapFs) Create
1
|
func (m *MemMapFs) Create(name string) (File, error)
|
func (*MemMapFs) List
1
|
func (m *MemMapFs) List()
|
func (*MemMapFs) Mkdir
1
|
func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error
|
func (*MemMapFs) MkdirAll
1
|
func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error
|
func (*MemMapFs) Name
1
|
func (*MemMapFs) Name() string
|
func (*MemMapFs) Open
1
|
func (m *MemMapFs) Open(name string) (File, error)
|
func (*MemMapFs) OpenFile
1
2
|
func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode)
(File, error)
|
func (*MemMapFs) Remove
1
|
func (m *MemMapFs) Remove(name string) error
|
func (*MemMapFs) RemoveAll
1
|
func (m *MemMapFs) RemoveAll(path string) error
|
func (*MemMapFs) Rename
1
|
func (m *MemMapFs) Rename(oldname, newname string) error
|
func (*MemMapFs) Stat
1
|
func (m *MemMapFs) Stat(name string) (os.FileInfo, error)
|
type OsFs
OsFs是使用os软件包提供的功能的Fs实现。
有关任何方法的详细信息,请检查os软件包的文档(http://golang.org/pkg/os/)。
func (OsFs) Chmod
1
|
func (OsFs) Chmod(name string, mode os.FileMode) error
|
func (OsFs) Chtimes
1
2
|
func (OsFs) Chtimes(name string, atime time.Time, mtime time.Time)
error
|
func (OsFs) Create
1
|
func (OsFs) Create(name string) (File, error)
|
func (OsFs) LstatIfPossible
1
|
func (OsFs) LstatIfPossible(name string) (os.FileInfo, bool, error)
|
func (OsFs) Mkdir
1
|
func (OsFs) Mkdir(name string, perm os.FileMode) error
|
func (OsFs) MkdirAll
1
|
func (OsFs) MkdirAll(path string, perm os.FileMode) error
|
func (OsFs) Name
1
|
func (OsFs) Name() string
|
func (OsFs) Open
1
|
func (OsFs) Open(name string) (File, error)
|
func (OsFs) OpenFile
1
2
|
func (OsFs) OpenFile(name string, flag int, perm os.FileMode) (File,
error)
|
func (OsFs) ReadlinkIfPossible
1
|
func (OsFs) ReadlinkIfPossible(name string) (string, error)
|
func (OsFs) Remove
1
|
func (OsFs) Remove(name string) error
|
func (OsFs) RemoveAll
1
|
func (OsFs) RemoveAll(path string) error
|
func (OsFs) Rename
1
|
func (OsFs) Rename(oldname, newname string) error
|
func (OsFs) Stat
1
|
func (OsFs) Stat(name string) (os.FileInfo, error)
|
func (OsFs) SymlinkIfPossible
1
|
func (OsFs) SymlinkIfPossible(oldname, newname string) error
|
type ReadOnlyFs
1
2
3
|
type ReadOnlyFs struct {
// contains filtered or unexported fields
}
|
func (*ReadOnlyFs) Chmod
1
|
func (r *ReadOnlyFs) Chmod(n string, m os.FileMode) error
|
func (*ReadOnlyFs) Chtimes
1
|
func (r *ReadOnlyFs) Chtimes(n string, a, m time.Time) error
|
func (*ReadOnlyFs) Create
1
|
func (r *ReadOnlyFs) Create(n string) (File, error)
|
func (*ReadOnlyFs) LstatIfPossible
1
2
|
func (r *ReadOnlyFs) LstatIfPossible(name string) (os.FileInfo, bool,
error)
|
func (*ReadOnlyFs) Mkdir
1
|
func (r *ReadOnlyFs) Mkdir(n string, p os.FileMode) error
|
func (*ReadOnlyFs) MkdirAll
1
|
func (r *ReadOnlyFs) MkdirAll(n string, p os.FileMode) error
|
func (*ReadOnlyFs) Name
1
|
func (r *ReadOnlyFs) Name() string
|
func (*ReadOnlyFs) Open
1
|
func (r *ReadOnlyFs) Open(n string) (File, error)
|
func (*ReadOnlyFs) OpenFile
1
2
|
func (r *ReadOnlyFs) OpenFile(name string, flag int, perm os.
FileMode) (File, error)
|
func (*ReadOnlyFs) ReadDir
1
|
func (r *ReadOnlyFs) ReadDir(name string) ([]os.FileInfo, error)
|
func (*ReadOnlyFs) ReadlinkIfPossible
1
|
func (r *ReadOnlyFs) ReadlinkIfPossible(name string) (string, error)
|
func (*ReadOnlyFs) Remove
1
|
func (r *ReadOnlyFs) Remove(n string) error
|
func (*ReadOnlyFs) RemoveAll
1
|
func (r *ReadOnlyFs) RemoveAll(p string) error
|
func (*ReadOnlyFs) Rename
1
|
func (r *ReadOnlyFs) Rename(o, n string) error
|
func (*ReadOnlyFs) Stat
1
|
func (r *ReadOnlyFs) Stat(name string) (os.FileInfo, error)
|
func (*ReadOnlyFs) SymlinkIfPossible
1
|
func (r *ReadOnlyFs) SymlinkIfPossible(oldname, newname string) error
|
type RegexpFile
1
|
type RegexpFile struct {
|
// contains filtered or unexported fields
}
func (*RegexpFile) Close
1
|
func (f *RegexpFile) Close() error
|
func (*RegexpFile) Name
1
|
func (f *RegexpFile) Name() string
|
func (*RegexpFile) Read
1
|
func (f *RegexpFile) Read(s []byte) (int, error)
|
func (*RegexpFile) ReadAt
1
|
func (f *RegexpFile) ReadAt(s []byte, o int64) (int, error)
|
func (*RegexpFile) Readdir
1
|
func (f *RegexpFile) Readdir(c int) (fi []os.FileInfo, err error)
|
func (*RegexpFile) Readdirnames
1
|
func (f *RegexpFile) Readdirnames(c int) (n []string, err error)
|
func (*RegexpFile) Seek
1
|
func (f *RegexpFile) Seek(o int64, w int) (int64, error)
|
func (*RegexpFile) Stat
1
|
func (f *RegexpFile) Stat() (os.FileInfo, error)
|
func (*RegexpFile) Sync
1
|
func (f *RegexpFile) Sync() error
|
func (*RegexpFile) Truncate
1
|
func (f *RegexpFile) Truncate(s int64) error
|
func (*RegexpFile) Write
1
|
func (f *RegexpFile) Write(s []byte) (int, error)
|
func (*RegexpFile) WriteAt
1
|
func (f *RegexpFile) WriteAt(s []byte, o int64) (int, error)
|
func (*RegexpFile) WriteString
1
|
func (f *RegexpFile) WriteString(s string) (int, error)
|
type RegexpFs
1
2
3
|
type RegexpFs struct {
// contains filtered or unexported fields
}
|
RegexpFs按正则表达式过滤文件(而不是目录)。只允许与给定的regexp匹配的文件,所有其他文件都会得到一个enent错误(“没有这样的文件或目录”)。
func (*RegexpFs) Chmod
1
|
func (r *RegexpFs) Chmod(name string, mode os.FileMode) error
|
func (*RegexpFs) Chtimes
1
|
func (r *RegexpFs) Chtimes(name string, a, m time.Time) error
|
func (*RegexpFs) Create
1
|
func (r *RegexpFs) Create(name string) (File, error)
|
func (*RegexpFs) Mkdir
1
|
func (r *RegexpFs) Mkdir(n string, p os.FileMode) error
|
func (*RegexpFs) MkdirAll
1
|
func (r *RegexpFs) MkdirAll(n string, p os.FileMode) error
|
func (*RegexpFs) Name
1
|
func (r *RegexpFs) Name() string
|
func (*RegexpFs) Open
1
|
func (r *RegexpFs) Open(name string) (File, error)
|
func (*RegexpFs) OpenFile
1
2
|
func (r *RegexpFs) OpenFile(name string, flag int, perm os.FileMode)
(File, error)
|
func (*RegexpFs) Remove
1
|
func (r *RegexpFs) Remove(name string) error
|
func (*RegexpFs) RemoveAll
1
|
func (r *RegexpFs) RemoveAll(p string) error
|
func (*RegexpFs) Rename
1
|
func (r *RegexpFs) Rename(oldname, newname string) error
|
func (*RegexpFs) Stat
1
|
func (r *RegexpFs) Stat(name string) (os.FileInfo, error)
|
type Symlinker
1
2
3
4
5
|
type Symlinker interface {
Lstater
Linker
LinkReader
}
|
符号链接器是Afero中的一个可选接口。它只由文件系统来实现。它表示支持实现操作系统方法行为的3个符号链接相关接口:
1
2
3
|
- Lstat
- Symlink, and
- Readlink
|
type UnionFile
1
2
3
4
5
6
|
type UnionFile struct {
Base File
Layer File
Merger DirsMerger
// contains filtered or unexported fields
}
|
UnionFile实现阿费罗文件接口,并将在读取至少存在于覆盖中的目录或打开文件进行写入时返回。
对Readdir()和Readdirnames() 的调用将合并文件操作系统文件信息/来自基础和覆盖层的名称-对于存在于两个层中的文件,将仅使用来自覆盖层的文件。
当打开文件进行写入时(Create() / OpenFile(),使用正确的标志),操作将在两个层中完成,从覆盖开始。覆盖层中的成功读取将使光标在基础层中的位置按读取的字节数移动。
func (*UnionFile) Close
1
|
func (f *UnionFile) Close() error
|
func (*UnionFile) Name
1
|
func (f *UnionFile) Name() string
|
func (*UnionFile) Read
1
|
func (f *UnionFile) Read(s []byte) (int, error)
|
func (*UnionFile) ReadAt
1
|
func (f *UnionFile) ReadAt(s []byte, o int64) (int, error)
|
func (*UnionFile) Readdir
1
|
func (f *UnionFile) Readdir(c int) (ofi []os.FileInfo, err error)
|
Readdir将把两个目录编织在一起,并返回重叠目录的单一视图。在目录视图的末尾,错误是io.EOF如果c>0。
func (*UnionFile) Readdirnames
1
|
func (f *UnionFile) Readdirnames(c int) ([]string, error)
|
func (*UnionFile) Seek
1
|
func (f *UnionFile) Seek(o int64, w int) (pos int64, err error)
|
func (*UnionFile) Stat
1
|
func (f *UnionFile) Stat() (os.FileInfo, error)
|
func (*UnionFile) Sync
1
|
func (f *UnionFile) Sync() (err error)
|
func (*UnionFile) Truncate
1
|
func (f *UnionFile) Truncate(s int64) (err error)
|
func (*UnionFile) Write
1
|
func (f *UnionFile) Write(s []byte) (n int, err error)
|
func (*UnionFile) WriteAt
1
|
func (f *UnionFile) WriteAt(s []byte, o int64) (n int, err error)
|
func (*UnionFile) WriteString
1
|
func (f *UnionFile) WriteString(s string) (n int, err error)
|