Go的标准库并没有专门用来检查文件是否存在的函数(就像Python的os.path.exists)。惯用的做法是什么?


当前回答

这是我在Go 1.16中检查文件是否存在的方法

package main

import (
    "errors"
    "fmt"
    "io/fs"
    "os"
)

func main () {
    if _, err:= os.Stat("/path/to/file"); errors.Is(err, fs.ErrNotExist){
        fmt.Print(err.Error())
    } else {
        fmt.Print("file exists")
    }
}

其他回答

让我们先看几个方面,golang的os包提供的两个函数都不是实用程序,而是错误检查器,我的意思是说它们只是跨平台处理错误的包装器。

基本上如果os。如果这个函数没有给出任何错误,那就意味着这个文件存在,如果它有,你需要检查它是什么类型的错误,这里有两个函数os的使用。IsNotExist和os.IsExist。

这可以理解为文件抛出错误的Stat,因为它不存在,或者它抛出错误是因为它存在,并且有一些问题。

这些函数所接受的形参是类型错误的,尽管你可以将nil传递给它,但这没有意义。

这也说明了IsExist和!IsNotExist是两个完全不同的东西。

所以现在如果你想知道一个给定的文件是否存在于go中,我想最好的方法是:

if _, err := os.Stat(path/to/file); !os.IsNotExist(err){
   //TODO
} 

其他答案忽略的是,给函数的路径实际上可能是一个目录。下面的函数确保,路径确实是一个文件。

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

函数示例:

func file_is_exists(f string) bool {
    _, err := os.Stat(f)
    if os.IsNotExist(err) {
        return false
    }
    return err == nil
}

检查文件是否存在的最佳方法:

if _, err := os.Stat("/path/to/file"); err == nil || os.IsExist(err) {
    // your code here if file exists
}