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

When I use ioutil to read a file, it may return an error. But if I want to filter some error code, what should I do?

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

In the code snippet above, when a file has no permission, fmt.Println(err.Error()) will print "open xxxxx: permission denied. If I want to capture this kind error, how can I know that file read failed because permission was denied?

Should I search err.Error() for the string permission denied - this looks ungraceful. Is there any better way?

Thanks in advance.

Update

After trying @Intermernet solution, I found that it will not hit case os.ErrPermission, it will hit default and print "open xxx: Permission denied".

@Aedolon solution is ok, os.IsPermission(err) can tell that a file has failed with permission deny.

According to the current API, ioutil.ReadFile doesn't guarantee any specific behaviour except that it will return err == nil when successful. Even the syscall package doesn't actually guarantee a specific error.

The current implementation of ioutil.ReadFile uses os.Open, which will return *os.PathError when failing to open a file, not os.ErrPermission or anything else. os.PathError contains a field Err which is also an error - in this case, a syscall.Errno. The string "permission denied" is produced from a private table of error messages and it's both architecture and implementation-specific. In my Windows machine it says "Access is denied" instead.

AFAIK, the correct method is to use os.IsPermission(err), which will return true in case of lacking permissions.

ioutil.ReadFile() calls os.Open() and returns any error encountered there.

The os package defines some file related errors.

ErrInvalid = errors.New("invalid argument")
ErrPermission = errors.New("permission denied")
ErrExist = errors.New("file already exists")
ErrNotExist = errors.New("file does not exist")

The one you're after is 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)
    }
}