patherror open o_create library golang go filepath

open - os library golang



¿Cómo puedo abrir archivos usando rutas relativas en Go? (4)

Creo que Alec Thomas ha proporcionado The Answer, pero en mi experiencia no es infalible. Un problema que tuve al compilar recursos en el binario es que la compilación puede requerir mucha memoria, dependiendo del tamaño de sus activos. Si son pequeños, entonces probablemente no es nada de qué preocuparse. En mi caso particular, un archivo de fuente de 1 MB causaba que la compilación requiriera alrededor de 1GB de memoria para compilarse. Fue un problema porque quería que fuera obtenible en una Raspberry Pi. Esto fue con Go 1.0; las cosas pueden haber mejorado en Go 1.1.

Entonces, en ese caso particular, opto por simplemente usar el paquete go/build para encontrar el directorio fuente del programa en función de la ruta de importación. Por supuesto, esto requiere que sus objetivos tengan GOPATH una GOPATH y que la fuente esté disponible. Entonces, no es una solución ideal en todos los casos.

Estoy usando io/ioutil para leer un pequeño archivo de texto:

fileBytes, err := ioutil.ReadFile("/absolute/path/to/file.txt")

Y eso funciona bien, pero esto no es exactamente portátil. En mi caso, los archivos que quiero abrir están en mi GOPATH, por ejemplo:

/Users/matt/Dev/go/src/github.com/mholt/mypackage/data/file.txt

Dado que la carpeta de data desplaza junto con el código fuente, me gustaría simplemente especificar la ruta relativa:

data/file.txt

Pero luego me sale este error:

pánico: datos abiertos / archivo.txt: no existe tal archivo o directorio

¿Cómo puedo abrir archivos usando su ruta relativa, especialmente si viven junto a mi código Go?


Escribí gobundle para resolver exactamente este problema. Genera código fuente Go a partir de archivos de datos, que luego compila en su binario. A continuación, puede acceder a los datos del archivo a través de una capa similar a VFS. Es completamente portátil, admite agregar árboles de archivos completos, compresión, etc.

La desventaja es que necesita un paso intermedio para construir los archivos Go a partir de los datos de origen. Usualmente uso make para esto.

A continuación, le mostramos cómo iterar sobre todos los archivos en un paquete, leyendo los bytes:

for _, name := range bundle.Files() { r, _ := bundle.Open(name) b, _ := ioutil.ReadAll(r) fmt.Printf("file %s has length %d/n", name, len(b)) }

Puede ver un ejemplo real de su uso en mi paquete GeoIP . El Makefile genera el código y geoip.go usa el VFS.


Hmm ... el paquete path/filepath tiene Abs() que hace lo que necesito (hasta ahora) aunque es un poco incómodo:

absPath, _ := filepath.Abs("../mypackage/data/file.txt")

Luego uso absPath para cargar el archivo y funciona bien.

Tenga en cuenta que, en mi caso, los archivos de datos están en un paquete separado del paquete main desde el que estoy ejecutando el programa. Si todo estuviera en el mismo paquete, eliminaría el principal ../mypackage/ . Dado que este camino es obviamente relativo, los diferentes programas tendrán estructuras diferentes y necesitan que esto se ajuste en consecuencia.

Si hay una mejor manera de utilizar recursos externos con un programa Go y mantenerlo portátil, no dude en contribuir con otra respuesta.


esto parece funcionar bastante bien:

import "os" import "io/ioutil" pwd, _ := os.Getwd() txt, _ := ioutil.ReadFile(pwd+"/path/to/file.txt")