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(),许多人说这是最佳实践