英文:
How do I check for specific types of error among those returned by ioutil.ReadFile?
问题
当我使用ioutil
读取文件时,可能会返回一个错误。但是如果我想要过滤一些错误代码,我应该怎么做?
在上面的代码片段中,当文件没有权限时,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)
可以判断文件是否因为权限被拒绝而失败。
英文:
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.
答案1
得分: 11
根据当前的API,ioutil.ReadFile
除了在成功时返回err == nil
之外,不保证任何特定的行为。即使是syscall包也不能保证具体的错误。
ioutil.ReadFile
的当前实现使用了os.Open
,当无法打开文件时,它会返回*os.PathError
,而不是os.ErrPermission
或其他任何错误。os.PathError
包含一个名为Err
的字段,它也是一个错误 - 在这种情况下,是一个syscall.Errno
。字符串"permission denied"是从一个私有的错误消息表中生成的,它是与架构和实现相关的。在我的Windows机器上,它显示为"Access is denied"。
据我所知,正确的方法是使用os.IsPermission(err)
,当缺少权限时它会返回true
。
英文:
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.
答案2
得分: 4
根据文档,应该使用errors.Is
函数来测试返回的错误。
var (
// ErrInvalid 表示无效的参数。
// 当接收者为nil时,File上的方法将返回此错误。
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) {
// 处理文件不存在的情况
} else if errors.Is(err, os.ErrPermission) {
// 处理权限被拒绝的情况
} else {
panic(err)
}
}
英文:
Per documentation, errors returned should be tested against these errors using errors.Is
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"
)
As an example:
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)
}
}
答案3
得分: 2
ioutil.ReadFile()
调用 os.Open()
并返回遇到的任何错误。
>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:
//处理逻辑
case os.ErrPermission:
//处理逻辑
case os.ErrNotExist:
//处理逻辑
default:
fmt.Println(err)
}
}
英文:
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)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论