¿Cómo comprobar si un archivo existe en Go?

La biblioteca estándar de Go no tiene una función destinada exclusivamente a comprobar si un fichero existe o no (como la de Python os.path.exists). ¿Cuál es la forma idiomática de hacerlo?

Comentarios sobre la pregunta (5)
Solución

Para comprobar si un archivo no existe, equivalente a if not os.path.exists(filename) de Python:

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

Para comprobar si un archivo existe, equivalente a if os.path.exists(filename) de Python:

Editado: por comentarios recientes

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

}
Comentarios (4)

Respuesta de Caleb Spare publicada en la lista de correo de [gonuts][1].

...en la lista de correo; [...] No se necesita muy a menudo y [...] usando os.Stat es lo suficientemente fácil para los casos en que se requiera.

...y que no se puede hacer nada más; [...] Por ejemplo: si vas a abrir el archivo, no hay razón para comprobar si existe primero. El archivo podría desaparecer entre la comprobación y la apertura, y de todos modos usted'tendrá que comprobar el error os.Open de todos modos. Así que simplemente llama a os.IsNotExist(err) después de intentar para abrir el archivo, y ocuparse de su inexistencia allí (si eso requiere un manejo especial).

...y que no se puede hacer nada más; [...] No es necesario que compruebe las rutas existentes en absoluto (y debería't).

...y no es necesario que compruebe los caminos que existen;

  • os.MkdirAll funciona independientemente de si los caminos ya existen o no. (También necesitas comprobar el error de esa llamada).

`;

  • En lugar de usar os.Create, deberías usar os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) . De esa forma, obtendrás un error si el archivo ya existe. Además, esto no tiene una condición de raza con algo más que haga el archivo, a diferencia de tu versión que comprueba su existencia de antemano.

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

[1]: https://groups.google.com/forum/#!msg/golang-nuts/Ayx-BMNdMFo/4rL8FFHr8v4J

Comentarios (0)

Debe utilizar las funciones 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 está extraído de aquí.

Comentarios (1)

El ejemplo de user11617 es incorrecto; informará de que el archivo existe incluso en los casos en los que no existe, pero hubo un error de algún otro tipo.

La firma debería ser Exists(string) (bool, error). Y entonces, como sucede, los sitios de llamada no son mejores.

El código que escribió sería mejor como:

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

Pero yo sugiero esto en su lugar:

func Exists(name string) (bool, error) {
  _, err := os.Stat(name)
  if os.IsNotExist(err) {
    return false, nil
  }
  return err != nil, err
}
Comentarios (3)
    _, 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)
    }
Comentarios (0)

El ejemplo de la función:

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

Veamos primero algunos aspectos, tanto la función proporcionada por el paquete de os de golang no son utilidades sino verificadores de errores, lo que quiero decir es que son sólo un envoltorio para manejar los errores en la plataforma cruzada.

Así que básicamente si os.Stat si esta función no'no da ningún error que signifique que el archivo existe si necesita comprobar qué tipo de error es, aquí viene el uso de estas dos funciones os.IsNotExist y os.IsExist.

Esto puede entenderse como el "estado" del archivo que arroja un error porque no existe o es un error porque existe y hay algún problema con él.

El parámetro que toman estas funciones es del tipo "error", aunque podrías pasarle "nada" pero no tendría sentido.

Esto también apunta al hecho de que "IsExist" no es lo mismo que "IsNotExist", son dos cosas muy diferentes.

Así que 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
} 
Comentarios (0)

Lo que otras respuestas pasaron por alto, es que la ruta dada a la función podría ser en realidad un directorio. La siguiente función asegura, que la ruta es realmente un archivo.

func fileExists(filename string) bool {
info, err := os.Stat(nombre de archivo)
Si el sistema operativo no existe...
devolver falso...
}
volver !info.IsDir()
}

Otra cosa a señalar: Este código aún podría llevar a una condición de carrera, donde otro hilo o proceso borra o crea el archivo especificado, mientras la función fileExists está en marcha.

Si te preocupa esto, utiliza un bloqueo en tus hilos, serializa el acceso a esta función o utiliza un semáforo de interproceso si hay varias aplicaciones involucradas. Si hay otras aplicaciones involucradas, fuera de su control, usted... no tiene suerte, supongo.

Comentarios (0)