Saltar al contenido principal
eLearner.app
Módulo 8 · Lección 3 de 538/50 en el curso~14 min
Lecciones del módulo (3/5)

io y os: archivos y flujos

La lectura y escritura de archivos y transmisiones en Go gira en torno a dos paquetes complementarios: os (apertura, creación, metadatos, procesos) y io (las interfaces Reader/Writer que abstraen cualquier fuente de bytes).

Lectura y escritura de archivos: los atajos

Para archivos pequeños o de configuración, una sola llamada es suficiente:

Go
data, err := os.ReadFile("input.txt")        // returns []byte
if err != nil {
    return err
}
fmt.Println(string(data))

err = os.WriteFile("out.txt", []byte("ciao"), 0644)

os.ReadFile se abre, lee todo en la memoria y se cierra. Perfecto hasta unos pocos MB; Más allá de eso, la transmisión es mejor.

Abrir archivos para transmisión

Para archivos grandes o acceso incremental, abra el archivo y ciérrelo con defer:

Go
f, err := os.Open("big.txt")        // read-only
if err != nil {
    return err
}
defer f.Close()

buf := make([]byte, 4096)
for {
    n, err := f.Read(buf)
    if n > 0 {
        process(buf[:n])
    }
    if err == io.EOF {
        break
    }
    if err != nil {
        return err
    }
}

os.Open se abre en modo de solo lectura. Para escribir use os.Create (se trunca si existe) o os.OpenFile(path, flag, perm) con banderas como os.O_APPEND | os.O_CREATE | os.O_WRONLY.

io.Reader y io.Writer: las interfaces universales

Go
type Reader interface { Read(p []byte) (n int, err error) }
type Writer interface { Write(p []byte) (n int, err error) }

Dondequiera que la biblioteca estándar acepte un io.Reader puedes pasar un archivo (*os.File), una cadena (strings.NewReader), un *bytes.Buffer, una respuesta HTTP (resp.Body), un descompresor... Lo mismo ocurre con io.Writer.

Go
// Copy from a Reader to a Writer (e.g. download → file).
n, err := io.Copy(dst, src)

io.Copy es el caballo de batalla para las canalizaciones de bytes: maneja el almacenamiento en búfer y EOF correctamente. io.ReadAll(r) lee todo hasta EOF en un []byte.

os.Args: argumentos CLI

os.Args es una porción de cadenas: el índice 0 es el nombre del programa, desde 1 en los argumentos reales:

Go
func main() {
    if len(os.Args) < 2 {
        fmt.Fprintln(os.Stderr, "uso: prog <nome>")
        os.Exit(1)
    }
    fmt.Println("ciao", os.Args[1])
}

Para un análisis más estructurado (indicadores, valores predeterminados, ayuda), utilice el paquete flag de stdlib o bibliotecas externas como cobra.

CÓDIGOPH0, CÓDIGOPH1, CÓDIGOPH2

Estos son tres *os.File globales: siempre que se acepte un io.Reader o un io.Writer, puedes pasarlos.

Go
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin)  // echo

Ejercicios

Ejercicio#go.m8.l3.e1
Intentos: 0Cargando...

Imprima el primer argumento de la línea de comandos (os.Args[1]). Si falta, imprima 'manca argomento' y regrese.

Cargando editor...

Solución disponible después de 3 intentos

Ejercicio#go.m8.l3.e2
Intentos: 0Cargando...

Escriba la cadena 'ciao' en el archivo 'out.txt' con os.WriteFile (permisos 0644). Maneja el error.

Cargando editor...

Solución disponible después de 3 intentos

Cuestionario#go.m8.l3.e3
Listo

¿Cuál es el índice del NOMBRE DEL PROGRAMA en os.Args?

Go
fmt.Println(os.Args[???])
Opciones de respuesta