El paquete os en Go constituye la interfaz fundamental para interactuar con las capacidades del sistema operativo de manera agnóstica a la plataforam. Permite realizar tareas que van desde la gestión de archivos hasta el control de procesos y variables de entorno.
Gestión de Archivos y Directorios
Apertura y creación de archivos
Para trabajar con archivos, Go ofrece funciones directas que menejan descriptores de archivos de forma eficiente.
// Creación de un archivo nuevo
f, err := os.Create("bitacora.log")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// Apertura con permisos específicos
// O_RDWR: Lectura y escritura, O_APPEND: Añadir al final, O_CREATE: Crear si no existe
archivo, err := os.OpenFile("datos.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0664)
/* Modos comunes:
os.O_RDONLY // Solo lectura
os.O_WRONLY // Solo escritura
os.O_TRUNC // Vaciar el archivo al abrir
*/
Operaciones de lectura y escritura
El paquete permite manipular el flujo de bytes de manera granular.
// Escribir cadenas de texto
bytesEscritos, err := archivo.WriteString("Nueva entrada en el registro\n")
// Lectura controlada por buffer
buffer := make([]byte, 256)
leidos, err := archivo.Read(buffer)
// Desplazamiento del puntero (Seek)
// Moverse 50 bytes desde el inicio
nuevoPunto, err := archivo.Seek(50, 0)
Inspección de metadatos
Es posible obtaner información detallada del sistema de archivos mediante la estructura FileInfo.
meta, err := os.Stat("bitacora.log")
if os.IsNotExist(err) {
fmt.Println("El archivo no fue encontrado")
} else {
fmt.Printf("Nombre: %s\n", meta.Name())
fmt.Printf("Tamaño: %d bytes\n", meta.Size())
fmt.Printf("¿Es directorio?: %v\n", meta.IsDir())
fmt.Printf("Modo de permisos: %v\n", meta.Mode())
}
Administración del Sistema de Archivos
Directorios y Rutas
Creación y navegación por la jerarquía de carpetas.
// Crear una ruta completa de directorios
err := os.MkdirAll("proyectos/enero/salida", 0755)
// Listar el contenido de una carpeta
entradas, err := os.ReadDir(".")
for _, e := range entradas {
fmt.Println(e.Name(), e.Type())
}
Manipulación de Entidades
Acciones para renombrar, mover o eliminar recursos.
// Renombrado o movimiento
os.Rename("temporal.tmp", "final.dat")
// Borrado simple
os.Remove("archivo_viejo.txt")
// Borrado recursivo (peligroso)
os.RemoveAll("cache/")
// Cambio de permisos (Chmod)
os.Chmod("ejecutable.sh", 0777)
Entorno y Ejecución
Variables de Entorno y Contexto
Acceso a la configuración del sistema y del proceso actual.
// Consultar una variable
dbHost := os.Getenv("DB_HOST")
// Asignar valores temporales
os.Setenv("APP_STAGE", "production")
// Obtener el directorio de trabajo actual
dirActual, _ := os.Getwd()
// Capturar argumentos de la línea de comandos
// os.Args[0] es el nombre del binario
if len(os.Args) > 1 {
parametro := os.Args[1]
}
Control de Procesos
Gestión del ciclo de vida de la aplicación.
// ID del proceso actual
idProceso := os.Getpid()
// Finalizar la ejecución inmediatamente
if err != nil {
os.Exit(1) // Código 1 indica error
}
// Obtener el nombre del host
servidor, _ := os.Hostname()
Ejemplos Prácticos de Implementación
Utilidad de Copiado de Archivos
Un enfoque robusto para duplicar archivos utilizando el paquete io junto a os.
func ClonarArchivo(origen, destino string) error {
fOrigen, err := os.Open(origen)
if err != nil {
return err
}
defer fOrigen.Close()
fDestino, err := os.Create(destino)
if err != nil {
return err
}
defer fDestino.Close()
_, err = io.Copy(fDestino, fOrigen)
return err
}
Gestor de Configuración Local
Uso de os.UserConfigDir para almacenar ajustes de la aplicación según el estándar del SO.
type Ajustes struct {
Tema string `json:"tema"`
Puerto int `json:"puerto"`
}
func CargarAjustes(nombreApp string) (*Ajustes, error) {
base, _ := os.UserConfigDir()
ruta := filepath.Join(base, nombreApp, "config.json")
raw, err := os.ReadFile(ruta)
if err != nil {
return &Ajustes{Tema: "oscuro", Puerto: 3000}, nil
}
var cfg Ajustes
json.Unmarshal(raw, &cfg)
return &cfg, nil
}
Sistema de Logs con Rotación Básica
Implementación de un escritor que redirige la salida a un archivo físico.
func IniciarRegistro(ruta string) (*os.File, error) {
// Abrir para añadir, crear si no existe
f, err := os.OpenFile(ruta, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return nil, err
}
log.SetOutput(f)
log.Println("--- Sesión iniciada ---")
return f, nil
}
Trabajo con Archivos Temporales
Para operaciones que requieren almacenamiento volátil sin colisiones de nombres.
// Crear archivo temporal en el directorio por defecto del sistema
tmp, err := os.CreateTemp("", "proceso_*.tmp")
if err == nil {
defer os.Remove(tmp.Name()) // Limpieza automática
tmp.Write([]byte("datos volátiles"))
tmp.Close()
}