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")
    }
}

其他回答

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

if _, err := os.Stat("/path/to/file"); err == nil || os.IsExist(err) {
    // your code here if file 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
} 

首先要考虑的是,您很少只想检查一个文件是否存在。在大多数情况下,如果文件存在,您将尝试对它做一些事情。在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
}

函数示例:

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