Go的标准库并没有专门用来检查文件是否存在的函数(就像Python的os.path.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
}
其他回答
其他答案忽略的是,给函数的路径实际上可能是一个目录。下面的函数确保,路径确实是一个文件。
func fileExists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}
另一件需要指出的事情是:这段代码仍然可能导致竞态条件,即在fileExists函数运行时,另一个线程或进程删除或创建指定的文件。
如果您担心这一点,可以在线程中使用锁,序列化对该函数的访问,或者在涉及多个应用程序时使用进程间信号量。如果涉及到其他应用程序,超出了您的控制范围,我想您就不走运了。
答案由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
基本上
package main
import (
"fmt"
"os"
)
func fileExists(path string) bool {
_, err := os.Stat(path)
return !os.IsNotExist(err)
}
func main() {
var file string = "foo.txt"
exist := fileExists(file)
if exist {
fmt.Println("file exist")
} else {
fmt.Println("file not exists")
}
}
运行示例
另一种方法
与操作系统。开放
package main
import (
"fmt"
"os"
)
func fileExists(path string) bool {
_, err := os.Open(path) // For read access.
return err == nil
}
func main() {
fmt.Println(fileExists("d4d.txt"))
}
运行它
检查一个文件是否不存在,相当于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
}
这是我对一个文件存在方法的看法。它还检查文件是否为目录,如果出现错误,也会返回该文件。
// 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
}