17370845950

Go语言如何读取文件内容_使用os Open与io ReadAll读取文件
os.Open读取文件前必须检查错误,否则nil指针解引用会导致panic;需手动Close或用defer;io.ReadAll适合小文件全量读取;推荐优先使用os.ReadFile自动管理资源。

os.Open 读取文件前必须检查错误

Go 中 os.Open 不会自动创建文件,只支持只读打开;如果路径不存在或权限不足,它返回 *os.Filenil,错误非空。忽略错误直接调用 ReadAll 会导致 panic:panic: runtime error: invalid memory address or nil pointer dereference

  • 务必先判断 err != nil,再使用返回的 *os.File
  • os.Open 打开后需手动调用 Close(),否则文件描述符泄漏
  • 推荐用 defer f.Close(),但注意它在函数返回时才执行,若后续操作出错,Close() 仍会运行

io.ReadAll 读取全部内容并自动处理 EOF

io.ReadAll 是最简方式读取整个文件到内存([]byte),内部循环读取直到遇到 io.EOF 或其他错误。它不关心底层是否是文件、管道或网络连接,只要实现了 io.Reader 接口即可。

  • 适用于小文件(几 MB 以内),大文件易触发 OOM
  • 不会自动解码 UTF-8;返回的是原始字节,需手动转 string 或用 strings.NewReader 等进一步处理
  • 若传入已关闭的 *os.File,会立即返回 io

    .ErrClosed

完整可运行示例:安全读取文本文件

package main

import (
	"fmt"
	"io"
	"os"
)

func main() {
	f, err := os.Open("config.txt")
	if err != nil {
		fmt.Printf("打开文件失败:%v\n", err)
		return
	}
	defer f.Close() // 即使下面出错也确保关闭

	data, err := io.ReadAll(f)
	if err != nil {
		fmt.Printf("读取文件失败:%v\n", err)
		return
	}

	fmt.Printf("文件内容:%s", string(data))
}

更健壮的替代方案:os.ReadFile

Go 1.16+ 提供了 os.ReadFile,它内部封装了 os.Open + io.ReadAll + Close,一行搞定且自动处理资源释放。大多数场景下应优先用它,除非你需要控制打开模式(如 os.O_APPEND)或复用文件句柄。

  • os.ReadFile 默认以只读方式打开,行为等价于 os.Open 后立刻 ReadAllClose
  • 若文件不存在,错误信息是 open config.txt: no such file or directory,和 os.Open 一致
  • 它不支持自定义缓冲区或中断读取逻辑,灵活性低于手动组合
容易被忽略的是:即使用了 os.ReadFile,仍要检查错误——它不保证成功,只是省去了资源管理细节。