Skip to content

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,其他错误保留原错误(本轮不执行):

go
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。目录代替文件时错误类别可能随平台不同,不硬断言为权限错误。书面练习先说明输入文件字节,再预测输出,避免编辑器附加换行使期望不一致。

继续阅读