Go与文件:从打开到流式数据处理

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么在Go中处理文件不仅不可怕,反而很有趣?

\n\n

当我第一次打开Go语言中os包的文档时,感觉等待我的将是一堆枯燥的系统调用列举。但深入研究后我明白了:在Go中处理文件和文件系统不仅仅是读取字节。这是一个强大的工具,能让您完全掌控数据,无论是配置文件、日志、二进制文件还是整个CSV数据库。

\n\n

Go语言是为系统编程而生的,因此其作者(肯·汤普森、罗布·派克等人)将文件操作直接内置到了语言核心中。无需任何外部依赖,只有标准库,运行快速且可预测。在本文中,我们将涵盖所有场景:从简单的文件读取到递归遍历目录以及大数据流式处理。

\n\n

如果您正在使用Go编程,并希望自信地处理文件系统——您来对地方了。开始吧!

\n\n

基础:打开、读取、关闭

\n\n

第一步是打开文件。在Go中,这由os.Open()函数负责。它返回一个文件指针和一个错误。Go中的错误不是异常,而是值。必须始终检查它们。

\n\n
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

一行代码读取整个文件

\n\n

如果文件较小(几兆字节以内),可以使用os.ReadFile()(替代了已弃用的ioutil.ReadFile)。这对于配置文件或文本数据非常方便。

\n\n
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()进行更精细的控制(例如追加到末尾)。

\n\n
// 创建文件\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\n
file, 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\n

os.O_APPEND标志确保数据追加到末尾,而不是覆盖开头。

\n\n

目录操作:创建、删除、遍历

\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)\                

博客

书籍推荐