Go 语言文件处理
Go 标准库的 os 与 bufio 包覆盖了日常几乎全部文件操作:打开、创建、整读、逐行读、写、追加、遍历目录。Go 的错误处理惯例是:会失败的操作都返回 error,必须立即检查,"能处理就处理,处理不了也要 return 出去",绝不能静默忽略。(说明:未给全 import 的片段需放入带相应 import 的 main 函数运行)
os.Open 与 os.Create
package main
import (
"fmt"
"os"
)
func main() {
// os.Open 只读打开;os.Create 不存在则新建、存在则清空
f, err := os.Create("hello.txt")
if err != nil {
fmt.Println("创建失败:", err)
return // 失败立即返回
}
defer f.Close() // 惯例:打开成功就 defer 关闭
fmt.Fprintln(f, "第一行")
fmt.Println("写入完成") // 输出:写入完成
}
defer f.Close() 紧跟打开语句之后,无论函数后面怎么走,退出时都会关掉文件,避免句柄泄漏。
读取文件的三种方式
// 1) os.ReadFile 一次读完,最简单,适合小文件
data, _ := os.ReadFile("hello.txt")
fmt.Println(string(data)) // 输出:第一行
// 2) bufio.Scanner 逐行读,适合大文件、按行处理
file, err := os.Open("hello.txt")
if err == nil {
defer file.Close()
sc := bufio.NewScanner(file)
for sc.Scan() { // 每次迭代读出一行
fmt.Println("行:", sc.Text())
}
}
// 3) f.Read(buf) 分块读,自己控制缓冲区与循环
buf := make([]byte, 4) // 一块 4 字节
n, _ := file.Read(buf)
fmt.Println(string(buf[:n])) // 输出:第一(只读前 4 字节)
写入:os.WriteFile 与 bufio.Writer
// os.WriteFile 直接整体写入(覆盖),0644 是权限
os.WriteFile("a.txt", []byte("hello\n"), 0644)
// bufio.Writer 带缓冲,适合多次小写入
f, _ := os.OpenFile("a.txt", os.O_CREATE|os.O_WRONLY, 0644)
w := bufio.NewWriter(f) // 包装出缓冲写入器
w.WriteString("第一段\n")
w.WriteString("第二段\n")
w.Flush() // 关键:把缓冲真正刷到磁盘
f.Close()
bufio 先写进内存缓冲,必须调用 Flush() 才落盘,忘了 Flush 文件内容会缺失。
追加写入:O_APPEND
以追加模式打开,每次写入都自动落到文件末尾,不会覆盖已有内容:
f, err := os.OpenFile("log.txt",
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) // 追加+不存在则创建
if err != nil {
return
}
defer f.Close()
f.WriteString("新日志行\n") // 多次运行都会追加
遍历目录
递归遍历目录树用 filepath.Walk:它会自动走进每个子目录,把当前路径交给回调函数:
import "path/filepath"
err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
fmt.Println(path) // 逐个打印目录与文件名
return nil // 返回 error 可中止遍历
})
_ = err
小结:读文件有 ReadFile(整读)、Scanner(逐行)、Read(分块)三种;写文件记得 bufio 要 Flush;追加用 O_APPEND;统一"打开即 defer Close、处处检查 err",目录递归交给 filepath.Walk。