Go 读取文件失败
本轮只做理论正文与源码静态复核;下列命令、示例和测试均未执行。已有输出按代码推演或历史记录理解,不作为本轮运行证据。
从路径、权限和错误类型定位 os.ReadFile 失败。
适用于本地文件读取;先确认程序运行目录,再区分文件不存在、权限不足和路径类型错误。不要把所有错误都当成“文件不存在”。
排查步骤
1. 确认当前工作目录和目标路径
pwd
ls -l ./config.json预期结果: 目标文件在预期目录中;如果文件不在这里,使用绝对路径或明确的配置目录。
2. 读取并保留原始错误
调用 os.ReadFile 后,在同一个 err != nil 分支内分类,再返回带原始原因的错误。直接使用完整程序中的 run 函数,其中列出所需导入。
预期结果: 成功时输出字节数;失败时日志含具体路径和底层错误。
3. 按错误类型处理
在同一次读取的错误分支中,用 errors.Is(err, fs.ErrNotExist) 检查缺失路径,用 errors.Is(err, fs.ErrPermission) 检查权限不足;其他错误保留原因并向上传递。分类必须发生在返回之前,无需再次读取文件。
预期结果: 不存在与权限不足走不同排查路径;其余错误继续保留并上报。
常见报错
no such file or directory
原因: 相对路径基于进程工作目录,而非源代码所在目录。
处理方式: 输出 os.Getwd(),核对部署文件路径;必要时用配置传入绝对路径。
permission denied
原因: 运行用户无法读取文件,或无权穿过上级目录。
处理方式: 检查运行身份及文件、父目录权限;按最小权限原则修正。
相关文档
官方资料
片段组合与完整程序
Shell 的 pwd/ls 示例用于 Bash;PowerShell 对应 Get-Location、Get-Item。下面可独立保存为 main.go,使用 Go 标准库;相对路径基于启动目录,成功打印文件字节数,缺失文件输出 missing,权限错误输出 permission,其他错误保留原错误(本轮不执行):
package main
import (
"errors"
"fmt"
"io/fs"
"os"
)
func run() error {
data, err := os.ReadFile("config.json")
if err != nil {
switch {
case errors.Is(err, fs.ErrNotExist):
return fmt.Errorf("missing config: %w", err)
case errors.Is(err, fs.ErrPermission):
return fmt.Errorf("permission: %w", err)
default:
return fmt.Errorf("read config: %w", err)
}
}
fmt.Println(len(data))
return nil
}
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}输入推演:config.json 的原始内容若恰为两个字节 {}(没有换行/BOM),输出2、退出0;文件不存在输出带 missing 和底层路径的错误、退出1。目录代替文件时错误类别可能随平台不同,不硬断言为权限错误。书面练习先说明输入文件字节,再预测输出,避免编辑器附加换行使期望不一致。
继续阅读
- 知识专题
- 开发实践
- 开发实践