golang的fs除了定权限还能干什么?
golang 中文件 | Golang 中文学习文档详细学习文档!
搞懂 fs 包的核心 ——fs.FS 接口
fs.FS (接口) :这是一个“文件系统”的抽象。它只有一个方法 Open(name string)。
type FS interface {
// 打开一个文件,返回 fs.File 接口(又是一个规则)
Open(name string) (File, error)
}
只要某个类型实现了 Open() 方法,返回 fs.File 接口,它就是一个 “合法的fs”,能被 fs 包的所有工具函数操作。
读取磁盘上的文件(传统方式)os.ReadFile
package main
import (
"fmt"
"os"
)
func main() {
// 直接操作硬盘
data, _ := os.ReadFile("config.txt")
fmt.Println(string(data))
}
fs 模块(现代方式,更灵活)
现在我们把硬盘路径包装成一个 fs.FS 对象。这样你的函数以后可以接收任何来源的文件。
package main
import (
"fmt"
"io/fs"
"os"
)
// 这个函数不关心文件在哪,它只认 fs.FS 接口
func readMyConfig(fsys fs.FS) {
data, err := fs.ReadFile(fsys, "config.txt")
if err != nil {
fmt.Println("读取失败:", err)
return
}
fmt.Println("配置内容:", string(data))
}
func main() {
// 1. 将当前目录 (.) 包装成一个文件系统对象
dirFS := os.DirFS(".")
// 2. 传给通用函数
readMyConfig(dirFS)
}
fs 包常用的工具函数
fs 包提供了一批 “通用工具函数”,和 io 包的工具函数类似,都是基于 fs.FS 接口实现的:
| 函数 | 作用 | 通俗理解 |
|---|---|---|
fs.ReadFile(fsys, name) | 读取文件全部内容 | 等同于 io.ReadAll,但针对 fs.FS |
fs.WalkDir(fsys, root, fn) | 遍历目录下所有文件 / 子目录 | 通用版的 “遍历目录” |
fs.Stat(fsys, name) | 获取文件信息(大小、是否是目录) | 等同于 os.Stat,但针对 fs.FS |
fs.Glob(fsys, pattern) | 按通配符匹配文件(如 *.txt) | 找符合规则的文件 |
示例:用 fs.WalkDir 遍历目录
package main
import (
"fmt"
"io/fs"
"os"
)
func main() {
// 1. 把本地目录转成 fs.FS
localFS := os.DirFS(".")
// 2. 遍历当前目录下所有文件/目录
err := fs.WalkDir(localFS, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
// d.IsDir():判断是不是目录(通用规则)
fmt.Printf("路径:%s | 是目录:%t\n", path, d.IsDir())
return nil
})
if err != nil {
fmt.Println("遍历失败:", err)
}
}
fs 模块真正的威力:go:embed
这是 fs 最常用的场景。
package main
import (
"embed"
"fmt"
"io/fs"
)
var embededFiles embed.FS
func main() {
// 即使你把编译好的程序拷到没有 hello.txt 的机器上,它也能运行
// 因为文件已经“嵌入”在程序里了
content, _ := fs.ReadFile(embededFiles, "hello.txt")
fmt.Println(string(content))
}
- 可以把静态文件(如图片、SQL、配置)直接编译进你的二进制程序里,然后像操作文件一样操作它们。
package main
import (
"embed"
"fmt"
"io/fs"
)
// 关键:用 //go:embed 指令把 static 目录下的所有文件嵌入程序
//go:embed static/*
var embeddedFS embed.FS // embed.FS 实现了 fs.FS 接口
func main() {
// 用 fs 包的通用函数读取嵌入的文件
data, err := fs.ReadFile(embeddedFS, "static/index.html")
if err != nil {
fmt.Println("读取嵌入文件失败:", err)
return
}
fmt.Println("嵌入的 index.html 内容:", string(data))
}
- 把前端静态文件(HTML/CSS/JS)嵌入到 Go 程序里,打包后只有一个二进制文件,部署超方便。
一句话区分 os/io/fs:
os:操作本地文件的具体实现;io:定义读写数据的通用接口;fs:定义操作文件系统的通用接口。