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


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

Author: Sridhar Ratnakumar, 2012-09-20

7 answers

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

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

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

if _, err := os.Stat("/path/to/whatever"); !os.IsNotExist(err) {
  // path/to/whatever exists
}
 496
Author: Sridhar Ratnakumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-23 00:44:03

Respuesta de Caleb Sparepublicado en gonuts lista de correo.

[...] En realidad no es necesario muy a menudo y [...] usando os.Stat es bastante fácil para los casos donde se requiere.

[...] Por ejemplo: si va 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 tendrá que comprobar el error os.Open independientemente. Así que simplemente llama os.IsNotExist(err) después de que tratar para abrir el archivo, y tratar con su inexistencia allí (si eso requiere un manejo especial).

[...] No es necesario comprobar las rutas existentes en absoluto (y no debería).

  • os.MkdirAll funciona independientemente de si las rutas ya existen o no. (También es necesario comprobar el error de esa llamada.)

  • En lugar de usar os.Create, debe usar os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666). De esta manera obtendrás un error si el archivo ya existe. También esto no tiene una carrera condición con algo más haciendo el archivo, a diferencia de su versión que comprueba la existencia de antemano.

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

 91
Author: OscarRyz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-24 13:03:34

Debe usar 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 se extrae de aquí.

 21
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-21 09:10:44
    _, 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)
    }
 7
Author: tangxinfa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-29 02:58:11

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

La firma debe ser Exists(string) (bool, error). Y entonces, como sucede, los sitios de llamadas 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 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
}
 5
Author: user3431012,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:54

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
}
 5
Author: honmaple,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-11 05:51:52

Veamos primero algunos aspectos, tanto la función proporcionada por el paquete os de golang no son utilidades sino comprobadores de errores, lo que quiero decir con eso es que son solo una envoltura para manejar errores en multiplataforma.

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

Esto se puede entender como el Stat del archivo error de lanzamiento porque no existe o es error de lanzamiento porque existe y hay algún problema con él.

El parámetro que toman estas funciones es de tipo error, aunque podrías pasarle nil 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 es:

if _, err := os.Stat(path/to/file); !os.IsNotExist(err){
   //TODO
} 
 3
Author: Farhaan Bukhsh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-18 06:47:37