如何检查ioutil.ReadFile返回的特定错误类型?

时间:2014-05-04 03:04:10

标签: go

当我使用ioutil读取文件时,它可能会返回错误。但是,如果我想过滤一些错误代码,我该怎么办?

res, err := ioutil.ReadFile("xxx")
if err != nil {
    fmt.Println(err.Error())  
}
...

在上面的代码段中,当文件没有权限时,fmt.Println(err.Error())将打印"open xxxxx: permission denied。 如果我想捕获此类错误,我怎么知道文件读取失败,因为权限被拒绝了?

我应该在err.Error()搜索字符串permission denied - 这看起来很不合适。有没有更好的方法?

提前致谢。

更新

尝试@Intermernet解决方案后,我发现它不会点击case os.ErrPermission,它会点击default并打印"open xxx: Permission denied"

@Aedolon解决方案没问题,os.IsPermission(err)可以通过权限拒绝来判断文件是否已失败。

3 个答案:

答案 0 :(得分:8)

根据当前的API,ioutil.ReadFile并不保证任何特定的行为,但成功时会返回err == nil。即使是系统调用包实际上也不能保证特定的错误。

ioutil.ReadFile的当前实施使用os.Open,在未能打开文件时将返回*os.PathError,而不是os.ErrPermission或其他任何内容。 os.PathError包含字段Err,这也是一个错误 - 在本例中为syscall.Errno。字符串"权限被拒绝"是由私有的错误消息表生成的,它既是体系结构,也是特定于实现的。在我的Windows机器中它说"访问被拒绝"代替。

AFAIK,正确的方法是使用os.IsPermission(err),如果缺少权限,将返回true

答案 1 :(得分:2)

ioutil.ReadFile()调用os.Open()并返回在那里遇到的任何错误。

os package定义了一些file related errors

  

ErrInvalid = errors.New("无效的参数")
  ErrPermission = errors.New("权限被拒绝")
  ErrExist = errors.New("文件已经存在")
  ErrNotExist = errors.New("文件不存在")

你所追求的是os.ErrPermission

res, err := ioutil.ReadFile("xxx")
if err != nil {
    switch err {
    case os.ErrInvalid:
        //Do stuff
    case os.ErrPermission:
        //Do stuff
    case os.ErrNotExist:
        //Do stuff
    default:
        fmt.Println(err)
    }
}

答案 2 :(得分:1)

对于每个documentation,应使用错误针对返回的错误进行测试。是

var (
// ErrInvalid indicates an invalid argument.
// Methods on File will return this error when the receiver is nil.
ErrInvalid = errInvalid() // "invalid argument"

ErrPermission = errPermission() // "permission denied"
ErrExist      = errExist()      // "file already exists"
ErrNotExist   = errNotExist()   // "file does not exist"
ErrClosed     = errClosed()     // "file already closed"
ErrNoDeadline = errNoDeadline() // "file type does not support deadline"
)

例如:

f, err := ioutil.ReadFile("your_file")

if err != nil {
    if errors.Is(err, os.ErrNotExist) {
        // your code
    } else if errors.Is(err, os.ErrPermission) {
        // your code
    } else {
        panic(err)
    }
}