Trabajo con el sistema de archivos en Go: en la práctica
\n\nTrabajar con el sistema de archivos es una de las tareas básicas de cualquier aplicación de servidor. El lenguaje Go (Golang) proporciona un conjunto de herramientas potente y elegante para leer, escribir, eliminar y gestionar archivos y directorios. En este artículo, analizaremos ejemplos prácticos de trabajo con archivos en Go, utilizando los paquetes estándar os, io/ioutil (hasta Go 1.16) y io. Aprenderás cómo gestionar eficazmente los datos en el disco, manejar errores y escribir código limpio.
1. Fundamentos: apertura, lectura y escritura de archivos
\n\nEmpecemos con las operaciones más comunes. Para abrir un archivo se utiliza la función os.OpenFile o envoltorios más simples como os.Create y os.Open. Veamos un ejemplo de lectura de un archivo completo en memoria:
package main\n\nimport (\n "fmt"\n "os"\n)\n\nfunc main() {\n // Lectura de todo el archivo (antes de Go 1.16 se usaba ioutil.ReadFile)\n data, err := os.ReadFile("example.txt")\n if err != nil {\n fmt.Println("Error al leer el archivo:", err)\n return\n }\n fmt.Println("Contenido del archivo:")\n fmt.Println(string(data))\n}\n\n\nPara escribir datos en un archivo, usa os.WriteFile:
package main\n\nimport (\n "os"\n)\n\nfunc main() {\n content := []byte("¡Hola, mundo Go!\\nSegunda línea.")\n err := os.WriteFile("output.txt", content, 0644)\n if err != nil {\n panic(err)\n }\n // El archivo output.txt se ha creado y contiene nuestro texto\n}\n\n\nSi necesitas añadir datos al final de un archivo, usa las banderas:
\n\nfile, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\nif err != nil {\n panic(err)\n}\ndefer file.Close()\n\nif _, err := file.WriteString("Nueva entrada en el log\\n"); err != nil {\n panic(err)\n}\n\n\n2. Trabajo con directorios: creación, eliminación y recorrido
\n\nGestionar carpetas es una tarea igualmente importante. Puedes crear un nuevo directorio con os.Mkdir (una sola carpeta) o os.MkdirAll (de forma recursiva, como mkdir -p):
package main\n\nimport (\n "fmt"\n "os"\n)\n\nfunc main() {\n // Creamos una sola carpeta\n err := os.Mkdir("data", 0755)\n if err != nil {\n fmt.Println("Error al crear la carpeta:", err)\n }\n\n // Creamos una estructura anidada de forma recursiva\n err = os.MkdirAll("data/subdir/logs", 0755)\n if err != nil {\n fmt.Println("Error:", err)\n }\n}\n\n\nPara recorrer un directorio, puedes usar la función os.ReadDir (reemplazo de ioutil.ReadDir):
entries, err := os.ReadDir(".")\nif err != nil {\n panic(err)\n}\n\nfor _, entry := range entries {\n fmt.Printf("Nombre: %s, Carpeta: %t\\n", entry.Name(), entry.IsDir())\n}\n\n\nY para un recorrido recursivo de todos los archivos y carpetas, usa filepath.Walk del paquete path/filepath:
package main\n\nimport (\n "fmt"\n "os"\n "path/filepath"\n)\n\nfunc main() {\n err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {\n if err != nil {\n return err\n }\n fmt.Println(path)\n return nil\n })\n if err != nil {\n fmt.Println("Error al recorrer:", err)\n }\n}\n\n\nLa eliminación de archivos y carpetas se realiza con las funciones os.Remove y os.RemoveAll:
// Eliminar un solo archivo o carpeta vacía\nos.Remove("temp.txt")\n\n// Eliminar una carpeta con todo su contenido (análogo a rm -rf)\nos.RemoveAll("data")\n\n\n3. Técnicas avanzadas: entrada/salida con búfer y trabajo con archivos temporales
\n\nPara archivos grandes, no es eficiente leer todo el contenido en memoria. Usa la lectura con búfer mediante bufio:
package main\n\nimport (\n "bufio"\n "