¿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?
390
8
Para comprobar si un archivo no existe, equivalente a
if not os.path.exists(filename)
de Python:Para comprobar si un archivo existe, equivalente a
if os.path.exists(filename)
de Python:Editado: por comentarios recientes
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 aos.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).`;
os.Create
, deberías usaros.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
Debe utilizar las funciones
os.Stat()
yos.IsNotExist()
como en el siguiente ejemplo:El ejemplo está extraído de aquí.
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:
Pero yo sugiero esto en su lugar:
El ejemplo de la función:
Veamos primero algunos aspectos, tanto la función proporcionada por el paquete de
os
degolang
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 funcionesos.IsNotExist
yos.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:
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.
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.