Как проверить, существует ли файл в Go?

Стандартная библиотека

Go не имеет функции, предназначенной только для проверки наличия файла или нет (например, Python os.path.exists). Что такое идиоматический способ сделать это?

Ответ 1

Чтобы проверить, не существует ли файл, эквивалентный Python, if not os.path.exists(filename):

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

Чтобы проверить, существует ли файл, эквивалентный Python, if os.path.exists(filename):

Отредактировано: за последние комментарии

if _, err := os.Stat("/path/to/whatever"); err == nil {
  // path/to/whatever exists

} else if os.IsNotExist(err) {
  // 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


}

Ответ 2

Ответа на этот вопрос Caleb Spare в gonuts.

[...] На самом деле это не очень часто, и [...] используя os.Stat is достаточно легко для тех случаев, когда это необходимо.

[...] Например: если вы собираетесь открыть файл, нет никаких оснований проверять, существует ли он в первую очередь. Файл может исчезнуть между проверкой и открытием, и в любом случае вам нужно проверить ошибку 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

Ответ 3

Вы должны использовать функции 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
}

Пример извлечен из здесь.

Ответ 4

Пример user11617 неверен; он сообщит, что файл существует даже в тех случаях, когда его нет, но произошла ошибка какого-либо другого рода.

Подпись должна быть Exists (string) (bool, error). И тогда, как это бывает, сайты вызовов не лучше.

Код, который он написал, будет лучше:

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

Но я предлагаю это вместо:

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

Ответ 5

    _, 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

Пример функции:

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

Ответ 7

Давайте сначала рассмотрим несколько аспектов: обе функции, предоставляемые пакетом os golang - это не утилиты, а средства проверки ошибок. golang этим я подразумеваю, что они являются просто оболочкой для обработки ошибок на кроссплатформенной платформе.

Таким образом, в основном, если os.Stat если эта функция не os.Stat никакой ошибки, что означает, что файл существует, если вам нужно проверить, какая это ошибка, здесь используются две эти функции: os.IsNotExist и os.IsExist,

Это может быть понято как Stat ошибки выброса файла, потому что это не существует, или это ошибка выброса, потому что это существует, и есть некоторая проблема с этим.

Параметр, который принимают эти функции, имеет тип error, хотя вы можете передать ему nil но это не имеет смысла.

Это также указывает на тот факт, что IsExist is not same as !IsNotExist, это две разные вещи.

Так что теперь, если вы хотите знать, существует ли данный файл в go, я бы предпочел лучший способ:

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

Ответ 8

Что пропустили другие ответы, так это то, что путь к функции может быть каталогом. Следующая функция гарантирует, что путь действительно является файлом.

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

Еще один момент, на который следует обратить внимание: этот код все еще может привести к состоянию гонки, когда другой поток или процесс удаляет или создает указанный файл во время работы функции fileExists.

Если вас это беспокоит, используйте блокировку в своих потоках, сериализуйте доступ к этой функции или используйте межпроцессный семафор, если задействовано несколько приложений. Думаю, если другие приложения задействованы вне вашего контроля, вам не повезло.

Ответ 9

https://github.com/030/go-utils

package main

import (
    "fmt"
    "github.com/030/go-utils"
)

func main() {
    fmt.Println(utils.FileExists("go.mod"))
}

возвращается

true