Go的标准库并没有专门用来检查文件是否存在的函数(就像Python的os.path.exists)。惯用的做法是什么?
当前回答
你应该使用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(),许多人说这是最佳实践
其他回答
其他答案忽略的是,给函数的路径实际上可能是一个目录。下面的函数确保,路径确实是一个文件。
func fileExists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}
另一件需要指出的事情是:这段代码仍然可能导致竞态条件,即在fileExists函数运行时,另一个线程或进程删除或创建指定的文件。
如果您担心这一点,可以在线程中使用锁,序列化对该函数的访问,或者在涉及多个应用程序时使用进程间信号量。如果涉及到其他应用程序,超出了您的控制范围,我想您就不走运了。
让我们先看几个方面,golang的os包提供的两个函数都不是实用程序,而是错误检查器,我的意思是说它们只是跨平台处理错误的包装器。
基本上如果os。如果这个函数没有给出任何错误,那就意味着这个文件存在,如果它有,你需要检查它是什么类型的错误,这里有两个函数os的使用。IsNotExist和os.IsExist。
这可以理解为文件抛出错误的Stat,因为它不存在,或者它抛出错误是因为它存在,并且有一些问题。
这些函数所接受的形参是类型错误的,尽管你可以将nil传递给它,但这没有意义。
这也说明了IsExist和!IsNotExist是两个完全不同的东西。
所以现在如果你想知道一个给定的文件是否存在于go中,我想最好的方法是:
if _, err := os.Stat(path/to/file); !os.IsNotExist(err){
//TODO
}
基本上
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"))
}
运行它
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
}
你应该使用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(),许多人说这是最佳实践