Go的标准库并没有专门用来检查文件是否存在的函数(就像Python的os.path.exists)。惯用的做法是什么?
当前回答
首先要考虑的是,您很少只想检查一个文件是否存在。在大多数情况下,如果文件存在,您将尝试对它做一些事情。在Go中,每当你试图对一个不存在的文件执行一些操作时,结果应该是一个特定的错误(os.ErrNotExist),最好的方法是检查返回的err值(例如在调用os.OpenFile(…)这样的函数时)是否为os.ErrNotExist。
这样做的推荐方法是:
file, err := os.OpenFile(...)
if os.IsNotExist(err) {
// handle the case where the file doesn't exist
}
但是,由于添加了错误。在Go 1.13(2019年底发布)中,新的建议是使用错误。是:
file, err := os.OpenFile(...)
if errors.Is(err, os.ErrNotExist) {
// handle the case where the file doesn't exist
}
通常最好避免使用os。在尝试对文件做一些事情之前,Stat检查文件是否存在,因为在对文件做一些事情之前,文件总是有可能被重命名、删除等。
然而,如果你接受这个警告,你真的,真的只是想检查一个文件是否存在,而不是继续对它做一些有用的事情(作为一个人为的例子,假设你正在编写一个毫无意义的CLI工具,告诉你一个文件是否存在,然后退出¯\_()_/¯),那么推荐的方法是:
if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) {
// file does not exist
} else {
// file exists
}
其他回答
这是我对一个文件存在方法的看法。它还检查文件是否为目录,如果出现错误,也会返回该文件。
// FileExists checks if a file exists (and it is not a directory).
func FileExists(filePath string) (bool, error) {
info, err := os.Stat(filePath)
if err == nil {
return !info.IsDir(), nil
}
if errors.Is(err, os.ErrNotExist) {
return false, nil
}
return false, err
}
_, err := os.Stat(file)
if err == nil {
log.Printf("file %s exists", file)
} else if os.IsNotExist(err) {
log.Printf("file %s not exists", file)
} else {
log.Printf("file %s stat error: %v", file, err)
}
答案由Caleb Spare张贴在gonuts邮件列表中。
[...] It's not actually needed very often and [...] using os.Stat is easy enough for the cases where it is required. [...] For instance: if you are going to open the file, there's no reason to check whether it exists first. The file could disappear in between checking and opening, and anyway you'll need to check the os.Open error regardless. So you simply call os.IsNotExist(err) after you try to open the file, and deal with its non-existence there (if that requires special handling). [...] You don't need to check for the paths existing at all (and you shouldn't). os.MkdirAll works whether or not the paths already exist. (Also you need to check the error from that call.) Instead of using os.Create, you should use os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) . That way you'll get an error if the file already exists. Also this doesn't have a race condition with something else making the file, unlike your version which checks for existence beforehand.
摘自:https://groups.google.com/forum/#!味精rl8ffhr8v4j / golang-nuts / Ayx-BMNdMFo / 4
检查文件是否存在的最佳方法:
if _, err := os.Stat("/path/to/file"); err == nil || os.IsExist(err) {
// your code here if file exists
}
首先要考虑的是,您很少只想检查一个文件是否存在。在大多数情况下,如果文件存在,您将尝试对它做一些事情。在Go中,每当你试图对一个不存在的文件执行一些操作时,结果应该是一个特定的错误(os.ErrNotExist),最好的方法是检查返回的err值(例如在调用os.OpenFile(…)这样的函数时)是否为os.ErrNotExist。
这样做的推荐方法是:
file, err := os.OpenFile(...)
if os.IsNotExist(err) {
// handle the case where the file doesn't exist
}
但是,由于添加了错误。在Go 1.13(2019年底发布)中,新的建议是使用错误。是:
file, err := os.OpenFile(...)
if errors.Is(err, os.ErrNotExist) {
// handle the case where the file doesn't exist
}
通常最好避免使用os。在尝试对文件做一些事情之前,Stat检查文件是否存在,因为在对文件做一些事情之前,文件总是有可能被重命名、删除等。
然而,如果你接受这个警告,你真的,真的只是想检查一个文件是否存在,而不是继续对它做一些有用的事情(作为一个人为的例子,假设你正在编写一个毫无意义的CLI工具,告诉你一个文件是否存在,然后退出¯\_()_/¯),那么推荐的方法是:
if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) {
// file does not exist
} else {
// file exists
}