Convertimos bytes en flujo: io.Reader desde []byte en Go

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿Por qué podría necesitar convertir bytes en un flujo?

\n\n

Imagine la situación: ha escrito un excelente servicio en Go que recibe datos de una API externa. La respuesta llega como un arreglo de bytes ([]byte). Todo estaría bien, pero hay un problema: la siguiente función en su pipeline requiere como entrada no un slice de bytes, sino la interfaz io.Reader. ¿Qué hacer? ¿Entrar en pánico? ¿Escribir una solución desde cero? ¡No! Basta con recordar bytes.NewReader.

\n\n

Esta pregunta es una de las más populares en Stack Overflow (¡miles de visitas!). Y con razón. En Go, el concepto de io.Reader es la base para trabajar con flujos de datos: archivos, conexiones de red, respuestas HTTP y, por supuesto, simplemente bytes en memoria. Si es un desarrollador Go principiante, tarde o temprano se encontrará con este obstáculo. Analicemos cómo sortearlo de manera elegante y eficiente.

\n\n

En este artículo, no solo daremos la instrucción simple de "use bytes.NewReader". Analizaremos por qué funciona, qué alternativas existen y mostraremos ejemplos reales de la vida. ¡Allá vamos!

\n\n

Teoría: ¿Qué es io.Reader y con qué se come?

\n\n

Antes de convertir, recordemos qué es io.Reader. Es una interfaz definida en la biblioteca estándar de Go:

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

Todo es genialmente simple. Cualquier estructura que tenga un método Read(p []byte) (int, error) satisface automáticamente la interfaz io.Reader. Esto permite escribir código universal para leer datos de cualquier fuente: archivo, socket, cadena, slice de bytes.

\n\n

¿Por qué es genial? Porque puede escribir una función que analice JSON, XML o simplemente copie datos, sin preocuparse de dónde provienen. Solo necesita un io.Reader. Es una abstracción de flujo.

\n\n

Pero, ¿qué hacer si ya tiene datos en memoria (por ejemplo, []byte)? Necesita un objeto que "finja" ser un flujo, pero que lea de su slice. Aquí es donde entra en escena bytes.NewReader.

\n\n

Método principal: bytes.NewReader

\n\n

Este es el camino más simple y correcto. La función bytes.NewReader toma un []byte y devuelve un puntero a la estructura bytes.Reader, que implementa io.Reader (así como io.ReadSeeker, io.WriterTo y otras interfaces útiles).

\n\n

Ejemplo 1: Uso básico

\n\n
package main\n\nimport (\n    "bytes"\n    "fmt"\n    "io"\n    "log"\n)\n\nfunc main() {\n    // Nuestro slice de bytes original\n    data := []byte("¡Hola, mundo! Estos son bytes.")\n\n    // Creamos un Reader a partir del slice de bytes\n    reader := bytes.NewReader(data)\n\n    // Leemos datos del reader en un buffer\n    buf := make([]byte, 10) // leemos de 10 en 10 bytes\n    for {\n        n, err := reader.Read(buf)\n        if err != nil {\n            if err == io.EOF {\n                break // terminamos la lectura\n            }\n            log.Fatal(err)\n        }\n        fmt.Printf("Leídos %d bytes: %s\\n", n, buf[:n])\n    }\n    // Output:\n    // Leídos 10 bytes: ¡Hola, mun\n    // Leídos 10 bytes: do! Estos \n    // Leídos 8 bytes: son bytes.\n}
\n\n

Observe: bytes.Reader se comporta como un flujo real. Cuando los datos se acaban, devuelve io.EOF. Todo es correcto.

\n\n

Ejemplo 2: Uso con io.Copy

\n\n

El escenario más común es copiar bytes a algún lugar (a un archivo, a una respuesta HTTP). Para esto, io.Copy es ideal:

\n\n
package main\n\nimport (\n    "bytes"\n    "fmt"\n    "io"\n    "os"\n)\n\nfunc main() {\n    data := []byte("Guardamos estos datos en un archivo.")\n    reader := bytes.NewReader(data)\n\n    // Creamos un archivo\n    file, err := os.Create("output.txt")\n    if err != nil {\n        panic(err)\n    }\n    defer file.Close()\n\n    // Copiamos del reader al archivo\n                

Blogs

Book Recommendations