file - read - standard library golang
¿Cómo comprobar si existe un archivo en Go? (7)
Debe usar las os.Stat()
y os.IsNotExist()
como en el siguiente ejemplo:
// 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
}
El ejemplo se extrae de here .
La biblioteca estándar de Go no tiene una función destinada únicamente a verificar si un archivo existe o no (como os.path.exists
de Python). ¿Cuál es la forma idiomática de hacerlo?
El ejemplo de la función:
func Exists(name string) (bool, error) {
err := os.Stat(name)
if os.IsNotExist(err) {
return false, nil
}
return err != nil, err
}
El ejemplo de user11617 es incorrecto; informará de que el archivo existe incluso en los casos en que no existe, pero se produjo un error de algún otro tipo.
La firma debe ser Exists (cadena) (bool, error). Y luego, como sucede, los sitios de llamadas no son mejores.
El código que escribió sería mejor como:
func file_is_exists(f string) bool {
_, err := os.Stat(f)
if os.IsNotExist(err) {
return false
}
return err == nil
}
Pero sugiero esto en su lugar:
func Exists(name string) bool {
_, err := os.Stat(name)
return !os.IsNotExist(err)
}
Para verificar si un archivo no existe, equivalente a Python''s if not os.path.exists(filename)
:
if _, err := os.Stat("/path/to/whatever"); os.IsNotExist(err) {
// path/to/whatever does not exist
}
Para verificar si existe un archivo, equivalente a Python''s if os.path.exists(filename)
:
if _, err := os.Stat("/path/to/whatever"); !os.IsNotExist(err) {
// path/to/whatever exists
}
Respuesta por Caleb Spare publicado en la lista de correo gonuts .
[...] En realidad no es necesario muy a menudo y [...] usar
os.Stat
es bastante fácil para los casos en que se requiere.[...] Por ejemplo: si va a abrir el archivo, no hay razón para verificar si existe primero. El archivo podría desaparecer entre la verificación y la apertura, y de todos modos tendrá que revisar el error
os.Open
independientemente. Por lo tanto, simplemente llame aos.IsNotExist(err)
después de intentar abrir el archivo, y trate su no existencia allí (si eso requiere un manejo especial).[...] No es necesario que compruebes las rutas existentes (y no deberías).
os.MkdirAll
funciona si las rutas ya existen o no. (También necesita verificar el error de esa llamada).En lugar de usar
os.Create
, debe usaros.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
. De esa manera obtendrá un error si el archivo ya existe. Además, esto no tiene una condición de carrera con otra cosa que hace el archivo, a diferencia de su versión que comprueba su existencia de antemano.
Tomado de: gonuts
Veamos algunos aspectos primero, tanto la función provista por el paquete os
de golang
no son utilidades sino verificadores de errores, lo que quiero decir con esto es que son solo una envoltura para manejar errores en plataformas cruzadas.
Básicamente, si os.Stat
si esta función no da ningún error, significa que el archivo existe, si necesita verificar qué tipo de error es, aquí viene el uso de estas dos funciones os.IsNotExist
y os.IsExist
.
Esto puede entenderse como el Stat
del error de lanzamiento del archivo porque no existe o es un error de lanzamiento porque existe y hay algún problema con él.
El parámetro que toman estas funciones es de tipo error
, aunque es posible que no pueda pasarle nada, pero no tendría sentido.
Esto también apunta al hecho de que IsExist is not same as !IsNotExist
, son dos cosas diferentes.
Así que ahora, si quieres saber si un archivo dado existe en Go, preferiría que la mejor manera sea:
if _, err := os.Stat(path/to/file); !os.IsNotExist(err){
//TODO
}
_, 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)
}