Go не имеет функции, предназначенной только для проверки наличия файла или нет (например, Python os.path.exists
). Что такое идиоматический способ сделать это?
Как проверить, существует ли файл в Go?
Ответ 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