如何检查Go中是否存在文件?

时间:2022-01-24 11:49:10

Go's standard library does not have a function solely intended to check if a file exists or not (like Python's os.path.exists). What is the idiomatic way to do it?

Go的标准库没有专门用于检查文件是否存在的函数(如Python的os.path.exists)。做这个的惯用方法是什么?

7 个解决方案

#1


481  

To check if a file doesn't exist, equivalent to Python's if not os.path.exists(filename):

要检查文件是否不存在,等效于Python的,如果不是os.path.exists(filename):

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

To check if a file exists, equivalent to Python's if os.path.exists(filename):

检查文件是否存在,等效于Python的os.path.exists(filename):

if _, err := os.Stat("/path/to/whatever"); err == nil {
  // path/to/whatever exists
}
// the path does not exist or some error occurred.

#2


89  

Answer by Caleb Spare posted in gonuts mailing list.

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

[...] It's not actually needed very often and [...] using os.Stat is easy enough for the cases where it is required.

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

[...] 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).

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

[...] 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.)

    无论路径是否已经存在,os.MkdirAll都能正常工作。 (您还需要检查该呼叫的错误。)

  • 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.

    您应该使用os.OpenFile(path,os.O_RDWR | os.O_CREATE | os.O_EXCL,0666),而不是使用os.Create。这样,如果文件已存在,您将收到错误。此外,没有其他制作文件的竞争条件,与预先检查存在的版本不同。

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

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

#3


21  

You should use the os.Stat() and os.IsNotExist() functions as in the following example:

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

// Exists reports whether the named file or directory exists.
func Exists(name string) bool {
    if _, err := os.Stat(name); err != nil {
    if os.IsNotExist(err) {
                return false
            }
    }
    return true
}

The example is extracted from here.

这个例子是从这里提取的。

#4


7  

    _, err := os.Stat(file)
    if err == nil {
        log.Printf("file %s exists", file)
    } else if os.IsNotExist(err) {
        log.Printf("file %s not exists", file)
    } else {
        log.Printf("file %s stat error: %v", file, err)
    }

#5


5  

The example by user11617 is incorrect; it will report that the file exists even in cases where it does not, but there was an error of some other sort.

user11617的示例不正确;它会报告该文件存在,即使它没有,但有一些其他类型的错误。

The signature should be Exists(string) (bool, error). And then, as it happens, the call sites are no better.

签名应该是Exists(字符串)(bool,错误)。然后,实际上,呼叫站点并没有更好。

The code he wrote would better as:

他写的代码更好:

func Exists(name string) bool {
    _, err := os.Stat(name)
    return !os.IsNotExist(err)
}

But I suggest this instead:

但我建议这样做:

func Exists(name string) (bool, error) {
  err := os.Stat(name)
  if os.IsNotExist(err) {
    return false, nil
  }
  return err != nil, err
}

#6


5  

The function example:

功能示例:

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

#7


2  

Let's look at few aspects first, both the function provided by os package of golang are not utilities but error checkers, what do I mean by that is they are just a wrapper to handle errors on cross platform.

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

So basically if os.Stat if this function doesn't give any error that means the file is existing if it does you need to check what kind of error it is, here comes the use of these two function os.IsNotExist and os.IsExist.

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

This can be understood as the Stat of the file throwing error because it doesn't exists or is it throwing error because it exist and there is some problem with it.

这可以理解为文件抛出错误的统计信息,因为它不存在或者因为它存在并且存在一些问题而抛出错误。

The parameter that these functions take is of type error, although you might be able to pass nil to it but it wouldn't make sense.

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

This also points to the fact that IsExist is not same as !IsNotExist, they are way two different things.

这也指出了IsExist与!IsNotExist不同的事实,它们是两种不同的东西。

So now if you want to know if a given file exist in go, I would prefer the best way is:

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

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

#1


481  

To check if a file doesn't exist, equivalent to Python's if not os.path.exists(filename):

要检查文件是否不存在,等效于Python的,如果不是os.path.exists(filename):

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

To check if a file exists, equivalent to Python's if os.path.exists(filename):

检查文件是否存在,等效于Python的os.path.exists(filename):

if _, err := os.Stat("/path/to/whatever"); err == nil {
  // path/to/whatever exists
}
// the path does not exist or some error occurred.

#2


89  

Answer by Caleb Spare posted in gonuts mailing list.

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

[...] It's not actually needed very often and [...] using os.Stat is easy enough for the cases where it is required.

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

[...] 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).

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

[...] 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.)

    无论路径是否已经存在,os.MkdirAll都能正常工作。 (您还需要检查该呼叫的错误。)

  • 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.

    您应该使用os.OpenFile(path,os.O_RDWR | os.O_CREATE | os.O_EXCL,0666),而不是使用os.Create。这样,如果文件已存在,您将收到错误。此外,没有其他制作文件的竞争条件,与预先检查存在的版本不同。

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

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

#3


21  

You should use the os.Stat() and os.IsNotExist() functions as in the following example:

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

// Exists reports whether the named file or directory exists.
func Exists(name string) bool {
    if _, err := os.Stat(name); err != nil {
    if os.IsNotExist(err) {
                return false
            }
    }
    return true
}

The example is extracted from here.

这个例子是从这里提取的。

#4


7  

    _, err := os.Stat(file)
    if err == nil {
        log.Printf("file %s exists", file)
    } else if os.IsNotExist(err) {
        log.Printf("file %s not exists", file)
    } else {
        log.Printf("file %s stat error: %v", file, err)
    }

#5


5  

The example by user11617 is incorrect; it will report that the file exists even in cases where it does not, but there was an error of some other sort.

user11617的示例不正确;它会报告该文件存在,即使它没有,但有一些其他类型的错误。

The signature should be Exists(string) (bool, error). And then, as it happens, the call sites are no better.

签名应该是Exists(字符串)(bool,错误)。然后,实际上,呼叫站点并没有更好。

The code he wrote would better as:

他写的代码更好:

func Exists(name string) bool {
    _, err := os.Stat(name)
    return !os.IsNotExist(err)
}

But I suggest this instead:

但我建议这样做:

func Exists(name string) (bool, error) {
  err := os.Stat(name)
  if os.IsNotExist(err) {
    return false, nil
  }
  return err != nil, err
}

#6


5  

The function example:

功能示例:

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

#7


2  

Let's look at few aspects first, both the function provided by os package of golang are not utilities but error checkers, what do I mean by that is they are just a wrapper to handle errors on cross platform.

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

So basically if os.Stat if this function doesn't give any error that means the file is existing if it does you need to check what kind of error it is, here comes the use of these two function os.IsNotExist and os.IsExist.

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

This can be understood as the Stat of the file throwing error because it doesn't exists or is it throwing error because it exist and there is some problem with it.

这可以理解为文件抛出错误的统计信息,因为它不存在或者因为它存在并且存在一些问题而抛出错误。

The parameter that these functions take is of type error, although you might be able to pass nil to it but it wouldn't make sense.

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

This also points to the fact that IsExist is not same as !IsNotExist, they are way two different things.

这也指出了IsExist与!IsNotExist不同的事实,它们是两种不同的东西。

So now if you want to know if a given file exist in go, I would prefer the best way is:

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

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