Go 语言入门教程
os 与 io 包
本教程共 80 篇 · 第 73 篇 · 更新于 2026-07-27 · 约 8 分钟阅读
GoGo 入门教程osio文件读写ReaderWriterio.Copy
73. os 与 io 包
本节目标:学会用 os 包读写文件,理解 io.Reader/Writer 接口,掌握 io.Copy 和环境变量操作。
os 包读文件
最简单的方式,os.ReadFile 一把读完(Go 1.16+):
data, err := os.ReadFile("config.txt")
if err != nil {
fmt.Println("读文件失败:", err)
return
}
fmt.Println(string(data))
适合小文件。大文件用流式读取更省内存。
os 包写文件
os.WriteFile 一把写入:
err := os.WriteFile("output.txt", []byte("hello world"), 0644)
if err != nil {
fmt.Println("写文件失败:", err)
}
第三个参数是文件权限,和 Linux 的 chmod 一样。0644 表示所有者可读写,其他人只读。
打开和创建文件
需要更多控制时,用 os.Open 和 os.Create:
// 只读打开
file, err := os.Open("input.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// 创建或截断(覆盖)
file, err := os.Create("output.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// 更精细的控制
file, err := os.OpenFile("app.log", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
常用打开标志:
| 标志 | 含义 |
|---|---|
os.O_RDONLY | 只读 |
os.O_WRONLY | 只写 |
os.O_RDWR | 读写 |
os.O_CREATE | 不存在就创建 |
os.O_APPEND | 追加 |
os.O_TRUNC | 存在就截断 |
Tip打开的文件记得
defer file.Close(),否则文件描述符泄漏,长时间运行会耗尽。
读写数据
*os.File 实现了 io.Reader 和 io.Writer 接口,可以直接读写:
file, _ := os.Create("test.txt")
defer file.Close()
// 写
n, err := file.Write([]byte("hello"))
// 或.WriteString("hello")
// 读
buf := make([]byte, 1024)
n, err := file.Read(buf)
Read 返回实际读取的字节数。读到末尾返回 io.EOF。
io.Reader 接口
io.Reader 是 Go 里最核心的接口之一,只有一方法:
type Reader interface {
Read(p []byte) (n int, err error)
}
文件、网络连接、压缩流、字符串都实现了它。只要是 Reader,就能用同一套代码读:
func countLines(r io.Reader) int {
scanner := bufio.NewScanner(r)
count := 0
for scanner.Scan() {
count++
}
return count
}
// 文件、网络、字符串都能传
countLines(file)
countLines(strings.NewReader("a\nb\nc"))
countLines(resp.Body)
io.Writer 接口
type Writer interface {
Write(p []byte) (n int, err error)
}
同样,文件、网络连接、缓冲区都实现了它。
io.Copy
io.Copy 把数据从 Reader 拷贝到 Writer,直到遇到 EOF:
// 文件拷贝
src, _ := os.Open("source.txt")
defer src.Close()
dst, _ := os.Create("dest.txt")
defer dst.Close()
n, err := io.Copy(dst, src)
fmt.Println("拷贝了", n, "字节")
不用自己写循环读写了,io.Copy 帮你搞定,还高效。
bufio 缓冲读写
直接 Read/Write 每次都走系统调用,频繁操作性能差。bufio 包提供缓冲:
// 缓冲读
file, _ := os.Open("data.txt")
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text() // 逐行读
fmt.Println(line)
}
// 缓冲写
file, _ := os.Create("out.txt")
defer file.Close()
writer := bufio.NewWriter(file)
writer.WriteString("buffered line\n")
writer.Flush() // 别忘了刷新
Note
bufio.Scanner默认按行扫描,单行上限 64KB。超大行要用Scanner.Buffer调大缓冲。
环境变量
// 读取
home := os.Getenv("HOME") // 不存在返回空字符串
val, ok := os.LookupEnv("DEBUG") // 区分空值和不存在
// 设置
os.Setenv("MY_VAR", "hello")
// 列出所有
for _, e := range os.Environ() {
fmt.Println(e)
}
Tip
os.Getenv不存在时返回空字符串,没法区分「值为空」和「没设」。要区分就用os.LookupEnv。
其他常用功能
os.Mkdir("logs", 0755) // 创建目录
os.MkdirAll("logs/app/2026", 0755) // 递归创建
os.Remove("temp.txt") // 删文件
os.RemoveAll("tempdir") // 递归删目录
os.Rename("old.txt", "new.txt") // 重命名
os.Exit(1) // 立即退出程序
os.Args // 命令行参数
os.TempDir() // 临时目录
小结
os.ReadFile/os.WriteFile:简单读写小文件os.Open/os.Create/os.OpenFile:精细控制打开方式- 打开文件务必
defer Close() io.Reader/io.Writer是核心接口,统一读写抽象io.Copy高效拷贝数据流bufio包提供缓冲读写和 Scanner 逐行读os.Getenv/Setenv操作环境变量
下一节讲 time 包。