fs

io/fs 包是 Go 1.16 引入的核心文件系统抽象层,提供了一套​​统一接口​​用于处理各种文件系统实现。

1 变量

// fs 包定义的通用文件系统错误
var (
    // 无效参数错误 (错误信息: "invalid argument")
    // 在以下情况下可能发生:
    // - 无效的文件路径
    // - 无效的文件打开标志
    // - 不支持的操作
    // 应使用 errors.Is(err, fs.ErrInvalid) 进行检测
    ErrInvalid    = errInvalid()

    // 权限不足错误 (错误信息: "permission denied")
    // 在以下情况下可能发生:
    // - 尝试写入只读文件
    // - 访问受限目录
    // - 文件系统权限不足
    // 应使用 errors.Is(err, fs.ErrPermission) 进行检测
    ErrPermission = errPermission()

    // 文件已存在错误 (错误信息: "file already exists")
    // 在以下情况下可能发生:
    // - 尝试创建已存在的文件
    // - 创建目录时目标目录已存在
    // 应使用 errors.Is(err, fs.ErrExist) 进行检测
    ErrExist      = errExist()

    // 文件不存在错误 (错误信息: "file does not exist")
    // 在以下情况下可能发生:
    // - 尝试打开不存在的文件
    // - 操作不存在的文件
    // 应使用 errors.Is(err, fs.ErrNotExist) 进行检测
    ErrNotExist   = errNotExist()

    // 文件已关闭错误 (错误信息: "file already closed")
    // 在以下情况下可能发生:
    // - 在已关闭的文件上执行操作
    // - 使用已关闭的文件系统
    // 应使用 errors.Is(err, fs.ErrClosed) 进行检测
    ErrClosed     = errClosed()
)

// SkipAll 用于在 WalkDirFunc 中停止目录遍历
// 当从 WalkDirFunc 回调函数中返回 SkipAll 时,表示:
// - 终止整个文件系统遍历
// - 跳过所有剩余文件和目录
// - 停止进一步回调
// 该值不作为错误返回
var SkipAll = errors.New("skip everything and stop the walk")

// SkipDir 用于在 WalkDirFunc 中跳过当前目录
// 当从 WalkDirFunc 回调函数中返回 SkipDir 时,表示:
// - 跳过当前目录的所有内容
// - 继续遍历同级目录
// - 仅对目录返回值有效
// 该值不作为错误返回
var SkipDir = errors.New("skip this directory")

2 函数

2.1 func FormatDirEntry(dir DirEntry) string

​作用​​:格式化目录条目信息为可读字符串

参数​​:

  • dir DirEntry:目录条目对象

​返回值​​:

  • string:格式化后的字符串,包含名称、类型和模式信息

注意​​:

  • 主要用于调试和日志输出

  • 实际应用中使用entry.Info()获取完整信息

  • 格式化方式可能随Go版本改变

2.2 func FormatFileInfo(info FileInfo) string

​作用​​:格式化文件信息为可读字符串

参数​​:

  • info FileInfo:文件信息对象

​返回值​​:

  • string:格式化后的字符串,包含模式、大小、修改时间和名称

注意​​:

  • 主要用于命令行工具和调试输出

  • 时间格式固定为本地时间格式

  • 实际应用中应使用info对象属性获取特定信息

2.3 func Glob(fsys FS, pattern string) (matches []string, err error)

​作用​​:查找文件系统中匹配模式的文件

参数​​:

  • fsys FS:文件系统对象

  • pattern string:通配符模式(支持*?[a-z]等)

​返回值​​:

  • matches []string:匹配的文件路径列表(相对路径)

  • err error:可能错误

​错误情况​​:

  • fs.ErrNotExist:模式匹配未找到文件

  • fs.ErrPermission:目录访问权限不足

  • ErrInvalidPattern:无效模式语法

注意​​:

  • 使用filepath.Match语法规则

  • 路径分隔符始终为/

  • 结果按路径字母顺序排序

  • 不支持**递归匹配

2.4 func ReadFile(fsys FS, name string) ([]byte, error)

​作用​​:读取文件系统中的文件内容

参数​​:

  • fsys FS:文件系统对象

  • name string:文件路径(相对路径)

​返回值​​:

  • []byte:文件内容字节切片

  • error:可能错误

​错误情况​​:

  • fs.ErrNotExist:文件不存在

  • fs.ErrPermission:文件读取权限不足

  • fs.ErrInvalid:路径无效或为目录

​注意​​:

  • 一次性读取整个文件,不适合大文件

  • 文件路径使用正向斜杠/

  • 内存文件系统可能返回非标准错误

  • 文件内容不会缓存

2.5 func ValidPath(name string) bool

​作用​​:验证路径字符串是否有效

参数​​:

  • name string:要验证的路径

​返回值​​:

  • bool:路径是否有效

​规则​​:

  • 非空字符串

  • 不包含/连续出现

  • 不以/开头(相对路径)

  • 不包含U+0000(空字符)

  • 不包含...路径段

注意​​:

  • 仅验证语法有效性,不检查路径是否存在

  • 设计用于fs.WalkDir等函数的前置检查

  • 无效路径示例:

    • ../file.txt

    • /absolute/path

    • dir//file

    • bad\path(含有反斜杠)

2.6 func WalkDir(fsys FS, root string, fn WalkDirFunc) error

​作用​​:递归遍历文件系统树

参数​​:

  • fsys FS:文件系统对象

  • root string:遍历起始路径

  • fn WalkDirFunc:遍历回调函数

回调函数返回值行为​​:

  • nil:继续遍历

  • SkipDir:跳过当前目录

  • SkipAll:立即终止整个遍历

  • 其他错误:终止遍历并返回该错误

错误情况​​:

  • 权限错误(fs.ErrPermission

  • 无效路径(fs.ErrInvalid

  • 回调函数返回的错误

注意​​:

  • 遍历顺序为字典序

  • 总是先处理文件再处理目录内容

  • 对大文件系统可能效率低

  • 使用SkipDir跳过目录

  • 使用SkipAll提前终止遍历

3 类型

3.1 DirEntry接口

DirEntry 接口表示从目录中读取的条目,提供文件/子目录的基本信息,避免立即调用Stat()的系统开销。

3.1.1 func FileInfoToDirEntry(info FileInfo) DirEntry

​作用​​:将FileInfo对象转换为DirEntry条目

​参数​​:

  • info FileInfo:文件信息对象

​返回值​​:

  • DirEntry:转换后的目录条目

  • infonil时返回nil

使用场景​​:

  • 需要将已存在的FileInfo对象用在期望DirEntry的API中

  • 避免重复查询文件信息

注意事项​​:

  • 转换后的DirEntry不包含原始路径信息

  • Info()方法始终返回转换时使用的FileInfo,即使文件已修改

  • 不适用于需要实时文件状态的场景

3.1.2 func ReadDir(fsys FS, name string) ([]DirEntry, error)

​作用​​:读取目录内容并按文件名排序

​参数​​:

  • fsys FS:文件系统实现

  • name string:目录路径(相对路径)

​返回值​​:

  • []DirEntry:目录条目切片(按文件名升序排序)

  • error:可能错误

3.2 FS接口

FS 是文件系统的抽象接口,提供对分层文件系统的访问能力,是所有文件系统操作的基础接口。

3.2.1 关键方法 Open

​作用​​:打开指定路径的文件 ​​声明​​:Open(name string) (File, error)​参数​​:

  • name string:文件路径(必须满足 ValidPath(name)

​返回值​​:

  • File:打开的文件对象

  • error:错误对象(通常为 *PathError 类型)

​错误情况​​:

  • *PathError 类型错误,其中:

    • Op 字段值为 "open"

    • Path 字段为传入的 name 参数

    • Err 字段描述具体问题:

      • ErrInvalid:路径无效(不满足 ValidPath(name)

      • ErrNotExist:文件不存在

      • ErrPermission:权限不足

​实现要求​​:

  1. 必须返回满足 io.Reader 接口的文件对象

  2. 文件使用后必须调用 Close() 释放资源

  3. 路径必须通过 ValidPath(name) 验证

  4. 错误信息必须封装为 *PathError

3.2.2 func Sub(fsys FS, dir string) (FS, error)

​作用​​:返回以指定目录为根的文件系统视图

参数​​:

  • fsys FS:父文件系统

  • dir string:子目录路径(相对路径)

​返回值​​:

  • FS:新的子目录文件系统

  • error:可能的错误

​实现原理​​:

  1. 如果 dir.,直接返回 fsys

  2. 如果 fsys 实现了 SubFS 接口,调用 fsys.Sub(dir)

  3. 否则返回包装的 FS,其 Open(name) 调用 fsys.Open(path.Join(dir, name))

​错误情况​​:

  • *PathError 类型错误:

    • ErrNotExist:子目录不存在

    • ErrInvalid:子目录路径无效

    • ErrPermission:无访问权限

3.3 File接口

File 接口是文件系统中最核心的接口之一,提供对单个文件的访问能力,是标准 os.File 的抽象版本。

3.4 FileInfo接口

FileInfo 接口提供文件的元数据信息,是文件系统中最基础也最核心的接口之一。

3.5 func Stat(fsys FS, name string) (FileInfo, error)

  • 核心作用

高效获取文件的元数据信息,避免手动打开文件并调用 Stat()

  • 参数说明

    • fsys FS:文件系统对象

    • name string:文件路径(相对路径)

  • 返回值

    • FileInfo:文件信息对象

    • error:可能错误

3.6 FileMode类型

FileMode 类型是Go文件系统中处理文件类型和权限的核心工具,它提供了跨平台的统一表示方式。

3.6.1 func (m FileMode) IsRegular() bool

​作用​​:检查是否为普通文件 ​​实现​​:return m&ModeType == 0

3.6.2 func (m FileMode) Type() FileMode

​作用​​:提取文件类型位

3.6.3 func (m FileMode) String() string

​作用​​:生成UNIX风格权限字符串 ​​格式​​:类型位 + 权限位(9字符)

3.6.4 func (m FileMode) Perm() FileMode

​作用​​:提取Unix权限位(移除类型位)

最后更新于