为什么在Go中处理文件不仅不可怕,反而很有趣?
\n\n当我第一次打开Go语言中os包的文档时,感觉等待我的将是一堆枯燥的系统调用列举。但深入研究后我明白了:在Go中处理文件和文件系统不仅仅是读取字节。这是一个强大的工具,能让您完全掌控数据,无论是配置文件、日志、二进制文件还是整个CSV数据库。
Go语言是为系统编程而生的,因此其作者(肯·汤普森、罗布·派克等人)将文件操作直接内置到了语言核心中。无需任何外部依赖,只有标准库,运行快速且可预测。在本文中,我们将涵盖所有场景:从简单的文件读取到递归遍历目录以及大数据流式处理。
\n\n如果您正在使用Go编程,并希望自信地处理文件系统——您来对地方了。开始吧!
\n\n基础:打开、读取、关闭
\n\n第一步是打开文件。在Go中,这由os.Open()函数负责。它返回一个文件指针和一个错误。Go中的错误不是异常,而是值。必须始终检查它们。
package main\n\nimport (\n "fmt"\n "os"\n)\n\nfunc main() {\n file, err := os.Open("example.txt")\n if err != nil {\n fmt.Println("打开文件错误:", err)\n return\n }\n defer file.Close() // 务必关闭文件\n\n // 读取内容\n buf := make([]byte, 1024)\n n, err := file.Read(buf)\n if err != nil {\n fmt.Println("读取错误:", err)\n return\n }\n fmt.Printf("读取了 %d 字节: %s\\n", n, string(buf[:n]))\n}\n\n\n请注意defer file.Close()。这是Go的惯用写法:延迟调用确保即使在发生panic或提前返回时文件也会被关闭。忘记关闭文件是不良实践,会导致描述符泄漏。
一行代码读取整个文件
\n\n如果文件较小(几兆字节以内),可以使用os.ReadFile()(替代了已弃用的ioutil.ReadFile)。这对于配置文件或文本数据非常方便。
data, err := os.ReadFile("config.yaml")\nif err != nil {\n log.Fatal(err)\n}\nfmt.Println(string(data))\n\n\n该函数会自动打开、读取并关闭文件。但请记住:对于大文件,这种方法很危险——您会将整个文件加载到内存中。
\n\n写入文件:创建与追加
\n\n写入时使用os.Create()(创建新文件或截断现有文件)以及os.OpenFile()进行更精细的控制(例如追加到末尾)。
// 创建文件\nfile, err := os.Create("output.txt")\nif err != nil {\n panic(err)\n}\ndefer file.Close()\n\n// 写入字符串\n_, err = file.WriteString("Hello, Go文件!\\n")\nif err != nil {\n panic(err)\n}\n\n// 写入字节\nbytes := []byte("写入字节切片\\n")\n_, err = file.Write(bytes)\nif err != nil {\n panic(err)\n}\n\n\n要将数据追加到现有文件末尾,请使用标志:
\n\nfile, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\nif err != nil {\n log.Fatal(err)\n}\ndefer file.Close()\n\nfile.WriteString("新的日志记录\\n")\n\n\nos.O_APPEND标志确保数据追加到末尾,而不是覆盖开头。
目录操作:创建、删除、遍历
\n\n文件系统不仅包含文件,还有文件夹。Go提供了方便的目录操作函数。
\n\n创建和删除文件夹
\n\n// 创建单个文件夹\nerr := os.Mkdir("newdir", 0755)\nif err != nil {\n log.Fatal(err)\n}\n\n// 创建嵌套文件夹(类似 mkdir -p)\nerr = os.MkdirAll("path/to/nested/dir", 0755)\nif err != nil {\n log.Fatal(err)\