Trabajo con el sistema de archivos en Go: guía práctica
Go (Golang) es un lenguaje compilado moderno, ideal para crear aplicaciones de servidor, utilidades y herramientas de línea de comandos. Una de las tareas clave en estos proyectos es trabajar con el sistema de archivos. En este artículo, exploraremos ejemplos prácticos: desde abrir y leer archivos hasta recorrer directorios de forma recursiva. Todos los ejemplos están escritos en Go puro, sin bibliotecas externas.
Fundamentos: abrir, leer y escribir archivos
El paquete os proporciona funciones para el trabajo de bajo nivel con archivos. Para leer todo el contenido de un archivo en memoria, use os.ReadFile (disponible desde Go 1.16).
package main
import ( "fmt" "os")
func main() { data, err := os.ReadFile("example.txt") if err != nil { fmt.Println("Error al leer el archivo:", err) return } fmt.Println(string(data))}Para escribir datos en un archivo, existe la función os.WriteFile. Crea el archivo si no existe, o sobrescribe el existente.
package main
import ( "fmt" "os")
func main() { content := []byte("¡Hola, Go!Segunda línea") err := os.WriteFile("output.txt", content, 0644) if err != nil { fmt.Println("Error al escribir:", err) return } fmt.Println("Archivo escrito exitosamente")}El tercer argumento 0644 son los permisos de acceso al estilo Unix (el propietario puede leer y escribir, los demás solo leer). En Windows, este parámetro se ignora parcialmente.
Lectura y escritura en flujo: trabajo con archivos grandes
Para trabajar con archivos grandes (de más de unos pocos megabytes), no se deben cargar completamente en memoria. Use la lectura almacenada en búfer con bufio o el paquete io.
package main
import ( "bufio" "fmt" "os")
func main() { file, err := os.Open("large_file.log") if err != nil { fmt.Println("Error al abrir:", err) return } defer file.Close()
scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() // Procesamos la línea fmt.Println(line) }
if err := scanner.Err(); err != nil { fmt.Println("Error de escaneo:", err) }}Para escritura en flujo, use bufio.NewWriter:
package main
import ( "bufio" "fmt" "os")
func main() { file, err := os.Create("output_stream.txt") if err != nil { fmt.Println("Error al crear:", err) return } defer file.Close()
writer := bufio.NewWriter(file) for i := 0; i < 10; i++ { _, err := writer.WriteString(fmt.Sprintf("Línea %d", i+1)) if err != nil { fmt.Println("Error al escribir:", err) return } } writer.Flush() // Importante: vaciamos el búfer fmt.Println("Escritura completada")}El método Flush() es obligatorio; sin él, los datos pueden permanecer en el búfer y no llegar al archivo.
Trabajo con directorios: creación, eliminación y recorrido
Se puede crear un nuevo directorio con os.Mkdir (una carpeta) o os.MkdirAll (de forma recursiva, como mkdir -p).
package main
import ( "fmt" "os")
func main() { // Crear una carpeta err := os.Mkdir("new_folder", 0755) if err != nil { fmt.Println("Error al crear la carpeta:", err) }
// Crear una estructura anidada err = os.MkdirAll("a/b/c/d", 0755) if err != nil { fmt.Println("Error al crear carpetas anidadas:", err) } else { fmt.Println("Carpetas creadas") }}La eliminación de un directorio se realiza con os.Remove (solo p