golang的fs除了定权限还能干什么?

0 阅读3分钟

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:定义操作文件系统的通用接口。