乐闻世界logo
搜索文章和话题

Golang 如何检查某个文件是否存在?

7 个月前提问
3 个月前修改
浏览次数74

6个答案

1
2
3
4
5
6

在Go语言中,检查文件是否存在有几种方法,但最常见和简单的方法是使用os.Stat函数和os.IsNotExist函数。下面是一个示例,展示了如何使用这两个函数来检查文件是否存在:

go
package main import ( "fmt" "os" ) // fileExists 检查文件是否存在,返回布尔值和可能出现的错误 func fileExists(filename string) (bool, error) { // 使用os.Stat获取文件信息 info, err := os.Stat(filename) if os.IsNotExist(err) { // 如果返回的错误类型为文件不存在,则说明文件确实不存在 return false, nil } // 如果info不为空,并且没有错误,则文件存在 return !info.IsDir(), err } func main() { // 检查文件"example.txt"是否存在 exists, err := fileExists("example.txt") if err != nil { // 如果有错误,打印错误并退出 fmt.Printf("Failed to check if file exists: %v\n", err) return } // 根据存在标志打印相应的信息 if exists { fmt.Println("File exists.") } else { fmt.Println("File does not exist.") } }

在上述代码中,fileExists函数会尝试获取指定文件的信息。如果os.Stat函数返回一个错误,并且通过os.IsNotExist检查确认这个错误是因为文件不存在,则fileExists会返回false和一个nil错误。如果没有错误,并且info.IsDir()也为false(意味着路径不是一个目录),则函数返回true

需要注意的是,文件可能因为其他原因而无法访问(例如权限问题),此时os.Stat会返回非nil的错误,这种情况下,你可能需要根据具体的错误类型来作出不同的处理。

2024年6月29日 12:07 回复

检查文件是否不存在,相当于Python的if not os.path.exists(filename)

shell
if _, err := os.Stat("/path/to/whatever"); errors.Is(err, os.ErrNotExist) { // path/to/whatever does not exist }

检查文件是否存在,相当于Python的if os.path.exists(filename)

编辑:根据最近的评论

shell
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 }
2024年6月29日 12:07 回复

Caleb Spare的回答发布在gonuts邮件列表中。

[...] 实际上并不经常需要它,并且 [...]os.Stat对于需要它的情况来说使用起来很容易。

[...] 例如:如果您要打开文件,则没有理由先检查它是否存在。该文件可能会在检查和打开之间消失,无论如何您都需要检查错误os.Open。因此,您只需在尝试打开文件后调用os.IsNotExist(err),并处理该文件不存在的情况(如果需要特殊处理)。

[...] 您根本不需要检查是否存在路径(而且您也不应该这样做)。

  • os.MkdirAll无论路径是否存在都有效。(您还需要检查该调用的错误。)

  • os.Create您应该使用而不是使用os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)。这样,如果文件已经存在,您将收到错误消息。此外,这与创建文件的其他内容不存在竞争条件,这与您事先检查是否存在的版本不同。

摘自: https: //groups.google.com/forum/#! msg/golang-nuts/Ayx-BMNdMFo/4rL8FFHr8v4J

2024年6月29日 12:07 回复

首先要考虑的是,您很少只想检查文件是否存在。在大多数情况下,您会尝试对文件(如果存在)执行某些操作。在 Go 中,任何时候你尝试对不存在的文件执行某些操作,结果都应该是一个特定的错误 ( os.ErrNotExist),最好的办法是检查返回err值(例如,当调用类似 的函数时os.OpenFile(...))是否为os.ErrNotExist

过去推荐的方法是:

shell
file, err := os.OpenFile(...) if os.IsNotExist(err) { // handle the case where the file doesn't exist }

然而,自从Go 1.13(2019 年底发布)中添加了,errors.Is新的建议是使用errors.Is

shell
file, err := os.OpenFile(...) if errors.Is(err, os.ErrNotExist) { // handle the case where the file doesn't exist }

通常最好避免os.Stat在尝试对文件执行某些操作之前使用它来检查文件是否存在,因为在执行某些操作之前,文件总是有可能在一段时间内被重命名、删除等。它。

然而,如果你同意这个警告,并且你真的只是想检查一个文件是否存在,然后不继续用它做一些有用的事情(作为一个人为的例子,假设你正在编写一个毫无意义的 CLI 工具,告诉你文件是否存在然后退出¯\_(ツ)_/¯),那么推荐的方法是:

shell
if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) { // file does not exist } else { // file exists }
2024年6月29日 12:07 回复

您应该使用os.Stat()os.IsNotExist()函数,如下例所示:

shell
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 }

edit1:修复了在某些情况下返回 true 的问题。
edit2:从os.IsNotExist()切换到使用errors.Is(),许多人说这是最佳实践,在这里

2024年6月29日 12:07 回复

其他答案错过的是,给函数的路径实际上可能是一个目录。以下函数可确保该路径确实是一个文件。

shell
func fileExists(filename string) bool { info, err := os.Stat(filename) if os.IsNotExist(err) { return false } return !info.IsDir() }

另一件需要指出的事情是:此代码仍然可能导致竞争条件,即在 fileExists 函数运行时另一个线程或进程删除或创建指定的文件。

如果您担心这一点,请在线程中使用锁,序列化对此函数的访问,或者在涉及多个应用程序时使用进程间信号量。如果涉及到超出您控制范围的其他应用程序,我想您就不走运了。

2024年6月29日 12:07 回复

你的答案