How to check if a file exists in Go?

2019-01-09 22:16发布

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?

7条回答
你好瞎i
2楼-- · 2019-01-09 22:26

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

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

查看更多
Rolldiameter
3楼-- · 2019-01-09 22:30

To check if a file doesn't exist, equivalent to Python's if not 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):

if _, err := os.Stat("/path/to/whatever"); !os.IsNotExist(err) {
  // path/to/whatever exists
}
查看更多
对你真心纯属浪费
4楼-- · 2019-01-09 22:35

Answer by Caleb Spare posted in gonuts mailing list.

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

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

查看更多
对你真心纯属浪费
5楼-- · 2019-01-09 22:45
    _, 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)
    }
查看更多
劳资没心,怎么记你
6楼-- · 2019-01-09 22:47

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.

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

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
}
查看更多
可以哭但决不认输i
7楼-- · 2019-01-09 22:51

The function example:

func file_is_exists(f string) bool {
    _, err := os.Stat(f)
    if os.IsNotExist(err) {
        return false
    }
    return err == nil
}
查看更多
登录 后发表回答