Go的标准库并没有专门用来检查文件是否存在的函数(就像Python的os.path.exists)。惯用的做法是什么?
当前回答
_, 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)
}
其他回答
检查一个文件是否不存在,相当于Python的if not os.path.exists(filename):
if _, err := os.Stat("/path/to/whatever"); errors.Is(err, os.ErrNotExist) {
// path/to/whatever does not exist
}
检查一个文件是否存在,相当于Python的if os.path.exists(filename):
编辑:根据最近的评论
if _, err := os.Stat("/path/to/whatever"); err == nil {
// path/to/whatever exists
} else if errors.Is(err, os.ErrNotExist) {
// path/to/whatever does *not* exist
} else {
// Schrodinger: file may or may not exist. See err for details.
// Therefore, do *NOT* use !os.IsNotExist(err) to test for file existence
}
你应该使用os.Stat()和os.IsNotExist()函数,如下例所示:
func Exists(name string) (bool, error) {
_, err := os.Stat(name)
if err == nil {
return true, nil
}
if errors.Is(err, os.ErrNotExist) {
return false, nil
}
return false, err
}
修正了在某些情况下返回true的问题。 edit2:从os.IsNotExist()切换到使用errors.Is(),许多人说这是最佳实践
检查文件是否存在的最佳方法:
if _, err := os.Stat("/path/to/file"); err == nil || os.IsExist(err) {
// your code here if file exists
}
user11617的示例不正确;即使在文件不存在的情况下,它也会报告文件存在,但存在其他类型的错误。
签名应该是Exists(string) (bool, error)。然后,碰巧的是,通话地点也没好到哪里去。
他编写的代码最好是:
func Exists(name string) bool {
_, err := os.Stat(name)
return !os.IsNotExist(err)
}
但我建议这样做:
func Exists(name string) (bool, error) {
_, err := os.Stat(name)
if os.IsNotExist(err) {
return false, nil
}
return err != nil, err
}
首先要考虑的是,您很少只想检查一个文件是否存在。在大多数情况下,如果文件存在,您将尝试对它做一些事情。在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
}