引入
Go sort 包 能排序数据,但数据通常来自文件或需要写入文件。Go 的文件操作围绕 os 包和 bufio 包展开,打开、读取、写入、关闭文件是日常开发的基本功。
正文
定义
定义
Go 文件操作主要通过
os包 打开和创建文件,用io包 的方法读写内容,用bufio包 实现带缓冲的高效读写。os.Open打开文件返回*os.File,它同时实现了io.Reader和io.Writer接口。
语法
import "os"
// 打开文件
f, err := os.Open("data.txt")
defer f.Close()
// 创建文件
f, err := os.Create("output.txt")
defer f.Close()
// 读取全部内容
data, err := os.ReadFile("data.txt")
// 写入全部内容
err = os.WriteFile("output.txt", data, 0644)例子
os.Open 读取文件
f, err := os.Open("data.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
buf := make([]byte, 1024)
n, err := f.Read(buf)
fmt.Println(string(buf[:n]))os.Open 以只读模式打开文件。Read 方法把内容读入字节切片,返回实际读取的字节数。用完必须 Close()。
os.Create 写入文件
f, err := os.Create("output.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
f.WriteString("hello world\n")
f.Write([]byte("second line\n"))os.Create 创建新文件或截断已有文件。返回的 *os.File 可写。
os.ReadFile 和 os.WriteFile
// 一次性读取全部内容
data, err := os.ReadFile("data.txt")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data))
// 一次性写入全部内容
err = os.WriteFile("output.txt", []byte("hello"), 0644)os.ReadFile 和 os.WriteFile 是最简便的读写方式,不需要手动打开关闭文件。适合小文件,大文件用流式读取。
os.OpenFile 自定义打开模式
// 追加模式打开
f, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE, 0644)
if err != nil {
log.Fatal(err)
}
defer f.Close()
f.WriteString("new log entry\n")os.OpenFile 能指定打开模式和权限。常用标志:
| 标志 | 说明 |
|---|---|
os.O_RDONLY | 只读 |
os.O_WRONLY | 只写 |
os.O_RDWR | 读写 |
os.O_CREATE | 不存在则创建 |
os.O_APPEND | 追加写入 |
os.O_TRUNC | 截断文件 |
bufio 带缓冲读取
f, _ := os.Open("data.txt")
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}bufio.NewScanner 按行读取文件,内存效率高,适合逐行处理大文件。scanner.Text() 返回当前行文本。
bufio 带缓冲写入
f, _ := os.Create("output.txt")
defer f.Close()
w := bufio.NewWriter(f)
w.WriteString("line 1\n")
w.WriteString("line 2\n")
w.Flush() // 必须调用,把缓冲区内容写入文件bufio.NewWriter 在内存中缓冲写入,减少磁盘 IO 次数。Flush() 必须调用,否则缓冲内容不会写入文件。
按字节分割读取
f, _ := os.Open("data.csv")
defer f.Close()
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanWords) // 按空格分割
for scanner.Scan() {
fmt.Println(scanner.Word())
}scanner.Split 设置分割方式:ScanLines(按行,默认)、ScanWords(按空格)、ScanRunes(按字符)、ScanBytes(按字节)。
文件信息
info, err := os.Stat("data.txt")
if err != nil {
log.Fatal(err)
}
fmt.Println(info.Name()) // data.txt
fmt.Println(info.Size()) // 文件字节数
fmt.Println(info.Mode()) // 权限
fmt.Println(info.ModTime()) // 修改时间
fmt.Println(info.IsDir()) // 是否目录os.Stat 获取文件信息。用 os.IsNotExist(err) 判断文件是否不存在。
常见写法
| 写法 | 说明 |
|---|---|
os.Open(name) | 只读打开文件 |
os.Create(name) | 创建或截断文件 |
os.OpenFile(name, flag, perm) | 自定义模式打开文件 |
os.ReadFile(name) | 一次性读取文件内容 |
os.WriteFile(name, data, perm) | 一次性写入文件 |
f.Close() | 关闭文件 |
f.Read(buf) / f.Write(buf) | 读写文件内容 |
bufio.NewScanner(f) | 带缓冲逐行读取 |
bufio.NewWriter(f) | 带缓冲写入 |
os.Stat(name) | 获取文件信息 |
os.IsNotExist(err) | 判断文件是否存在 |
os.Remove(name) | 删除文件 |
特点
os.Open只读,os.Create可写且截断,os.OpenFile最灵活- 打开的文件必须
Close(),用defer确保执行 os.ReadFile/os.WriteFile最简单,适合小文件一次性读写bufio.Scanner逐行读取,内存效率高,处理大文件首选bufio.NewWriter缓冲写入,Flush()必须调用*os.File同时实现了io.Reader和io.Writer,能配合 Go io 包 的函数使用
理解
Go 文件操作的核心思路:os.Open / os.Create 打开文件拿到 *os.File,然后用 Read / Write 或 bufio 读写内容,最后 defer f.Close() 收尾。小文件用 os.ReadFile 最省事,大文件用 bufio.Scanner 逐行处理。OpenFile 的 flag 组合看着多,记住 O_CREATE(创建)和 O_APPEND(追加)就够日常用了。
引出
文件操作是本地数据处理的基础,但很多应用还需要通过网络传输数据。接下来看 Go 网络编程,学习 TCP、UDP 等底层网络协议在 Go 中的实现。