¿Quieres una mejor comprensión de Buffer en Node.js? Mira esto.

¿Siempre estás desconcertado, como yo, cuando te encuentras con palabras como Buffer, Stream y datos binarios enNode.js? ¿Ese sentimiento te hace rehuir entenderlos, pensando que no son para ti, sino solo para que los gurús de Node.js y los desarrolladores de paquetes los entiendan?

De hecho, esas palabras pueden ser muy intimidantes, especialmente cuando ingresa al desarrollo web con Node.js sin ningún título de informática.

Lamentablemente, muchos tutoriales y libros pasarán directamente a enseñar cómo desarrollar aplicaciones web con paquetes Node.js sin permitirle comprender las características principales de Node.js y por qué existen. Y algunos te dirán descaradamente que no necesitas entenderlos porquepuede que nunca trabaje con ellos directamente.

Bueno, es cierto, es posible que nunca trabajes con ellos directamente si decides seguir siendo un desarrollador promedio de Node.js.

Sin embargo, si los misterios te dan mucha curiosidad y no te detendrás ante nada para satisfacer tu curiosidad, y si quieres llevar tu comprensión de Node.js al siguiente nivel, entonces realmente quieres profundizar para comprender las muchas características principales. de Node.js, como Buffer , por ejemplo. Y esa es exactamente la razón por la que escribo este artículo: para ayudarnos a desmitificar algunas de estas características y llevar nuestro aprendizaje de Node.js al siguiente nivel.

Al presentar Buffer , los documentos oficiales de Node.js indican en parte ...

… Mecanismo para leer o manipular flujos de datos binarios. La Bufferclase se introdujo como parte de la API Node.js para permitir la interacción con flujos de octetos en el contexto de cosas como flujos de TCP y operaciones del sistema de archivos.

Hmmm, a menos que tenga conocimiento previo de todas las palabras en las oraciones anteriores, probablemente sean solo un montón de jerga. Tratemos de simplificarlo un poco reformulándolo, para que podamos tener un enfoque claro y no distraernos con las muchas campanas y silbidos allí. Extrayendo de esa introducción, podríamos decir con seguridad:

La Bufferclase se introdujo como parte de la API de Node.js para que sea posible manipular o interactuar con flujos de datos binarios.

Ahora eso es más simple, ¿verdad? Pero… Buffer, streams, datos binarios… todavía hay muchas palabras importantes. Bueno, tratemos de abordar estas grandes palabras desde la última hasta la primera.

Datos binarios, ¿qué es eso?

Probablemente ya sepa que las computadoras almacenan y representan datos en binarios. Binario es simplemente un conjunto o una colección de unos y ceros. Por ejemplo, los siguientes son cinco binarios diferentes, cinco conjuntos diferentes de 1 y 0:

10, 01, 001, 1110,00101011

Cada número en un binario, cada uno 1y 0en un conjunto se denominan Bit , que es una forma abreviada de Binary digIT.

Para almacenar o representar un dato, una computadora necesita convertir esos datos a su representación binaria. Por ejemplo, para almacenar el número 12, una computadora necesita convertir 12 a su representación binaria que es 1100.

¿Cómo sabe una computadora cómo realizar esta conversión? Bueno, es pura matemática. Es el sistema numérico binario simple que aprendimos en matemáticas básicas: expresar un número en el sistema numérico de base 2. Las computadoras entienden esas matemáticas.

Pero los números no son el único tipo de datos con el que trabajamos. También tenemos cadenas, imágenes e incluso videos. Las computadoras saben cómo representar todo tipo de datos en binarios. Tomemos cadenas, por ejemplo. ¿Cómo representará una computadora la cadena "L" en binarios? Para almacenar cualquier carácter en binarios, las computadoras primero convertirán ese carácter en un número, luego convertirán ese número a su representación binaria. Entonces, para la cadena "L",ordenadores convertirá en primer lugar L a un número que representa L . Veamos cómo.

Abra su navegador de la consola y pegar el siguiente fragmento de código y luego pulsa enter: "L".charCodeAt(0). ¿Qué viste? ¿El número 76? Esa es la representación de números o caracteres de código o Punto Código del carácter L . Pero, ¿cómo sabe una computadora qué número exacto representará cada carácter? ¿Cómo sabe usar el número 76 para representar L ?

Conjuntos de caracteres

Los juegos de caracteres ya son reglas definidas de qué número exacto representa cada carácter. Tenemos diferentes definiciones de estas reglas, las más populares incluyen Unicode y ASCII . JavaScript funciona muy bien con los juegos de caracteres Unicode. De hecho, es el Unicode en su navegador que establece que 76 deben representar L .

Entonces, hemos visto cómo las computadoras representan caracteres en números. Ahora, la computadora, a su vez, representará el número 76 en su representación binaria. Podría pensar, bueno, simplemente convierta 76 al sistema numérico de base 2. ¡No tan rapido!

Codificación de caracteres

Así como existen reglas que definen qué número debe representar un carácter, también existen reglas que definen cómo ese número debe representarse en binarios. Específicamente, cuántos bits usar para representar el número. Esto se denomina codificación de caracteres .

Una de las definiciones para la codificación de caracteres es UTF-8 . UTF-8 establece que los caracteres deben codificarse en bytes. Un byte es un conjunto de ocho bits: ocho unos y ceros. Por lo tanto, se deben usar ocho 1 y 0 para representar el punto de código de cualquier carácter en binario.

Para entender esto, como mencionamos anteriormente, la representación binaria del número 12 es 1100. Entonces, cuando UTF-8 indica que 12 debe estar en ocho bits, UTF-8 dice que una computadora necesita agregar más bits al lado izquierdo de la representación real en base 2 del número 12 para convertirlo en un byte. Entonces, 12 deben almacenarse como 00001100. ¿Tiene sentido?

Por lo tanto, 76 debe almacenarse como 01001100.

Así, amigos míos, es como las computadoras almacenan cadenas o caracteres en binarios. Del mismo modo, las computadoras también tienen reglas específicas sobre cómo las imágenes y los videos deben convertirse o codificarse y almacenarse en binarios. El punto aquí es que las computadoras almacenan todos los tipos de datos en binarios, y esto se conoce como datos binarios.

Si está muy interesado en lo esencial de la codificación de caracteres, es posible que le guste esta introducción suave y detallada.

Ahora entendemos qué son los datos binarios, pero qué son los flujos de datos binariosde nuestra introducción a buffer?

Corriente

Transmitir en Node.js simplemente significa que una secuencia de datos se mueve de un punto a otro a lo largo del tiempo. El concepto general es que tiene una gran cantidad de datos para procesar, pero no necesita esperar a que todos los datos estén disponibles antes de comenzar a procesarlos.

Básicamente, estos grandes datos se desglosan y se envían en trozos. Entonces, a partir de la definición original de un búfer ("flujos de datos binarios ... en el contexto de ... sistema de archivos"), esto simplemente significa que los datos binarios se mueven en el sistema de archivos. Por ejemplo, moviendo los textos almacenados en file1.txt a file2.txt.

Pero, ¿cómo nos ayuda el búfer a interactuar o manipular datos binarios durante la transmisión? ¿Qué es exactamente este búfer por cierto?

Buffer

Hemos visto que un flujo de datos es el movimiento de datos de un punto a otro, pero ¿cómo se mueven exactamente ?

Por lo general, el movimiento de datos suele ser con la intención de procesarlos o leerlos y tomar decisiones en base a ellos. Pero hay una cantidad mínima y máxima de datos que un proceso puede tomar con el tiempo. Entonces, si la velocidad a la que llegan los datos es más rápida que la velocidad a la que el proceso consume los datos, el exceso de datos debe esperar en algún lugar para que se procese su turno.

Por otro lado, si el proceso consume los datos más rápido de lo que llegan, los pocos datos que llegan antes deben esperar a que llegue una cierta cantidad de datos antes de enviarlos para su procesamiento.

¡Esa "zona de espera " es el amortiguador! Es una pequeña ubicación física en su computadora, generalmente en la RAM, donde los datos se recopilan temporalmente, esperan y finalmente se envían para su procesamiento durante la transmisión.

Podemos pensar en todo el proceso de transmisión y búfer como una estación de autobuses. En algunas estaciones de autobuses, no se permite la salida de un autobús hasta que llegue una cierta cantidad de pasajeros o hasta una hora de salida específica. Además, los pasajeros pueden llegar en diferentes momentos con diferente velocidad. Ni los pasajeros ni la estación de autobuses tienen control sobre la llegada de los pasajeros a la estación.

En cualquier caso, los pasajeros que lleguen antes deberán esperar hasta que la estación de autobuses decida enviar el autobús en su camino. Mientras que los pasajeros que llegan cuando el autobús ya está subiendo o cuando el autobús ya ha salido deben esperar al próximo autobús.

En cualquier caso, siempre hay un lugar de espera. ¡Ese es el búfer para Node.js! Node.js no puede controlar la velocidad o el tiempo de llegada de los datos, la velocidad de la transmisión. Solo puede decidir cuándo es el momento de enviar los datos. Si aún no es el momento, Node.js los colocará en el búfer, el "área de espera", una pequeña ubicación en la RAM, hasta que sea el momento de enviarlos para su procesamiento.

Un ejemplo típico en el que puede ver el búfer en acción es cuando está transmitiendo un video en línea. Si su conexión a Internet es lo suficientemente rápida, la velocidad de la transmisión será lo suficientemente rápida como para llenar instantáneamente el búfer y enviarlo para su procesamiento, luego llenar otro y enviarlo, luego otro, y otro más ... hasta el flujo Está terminado.

Pero si su conexión es lenta, después de procesar el primer conjunto de datos que llegó, el reproductor de video mostrará un icono de carga o mostrará el texto "almacenando en búfer", lo que significa recopilar más datos o esperar a que lleguen más datos. Y cuando el búfer se llena y procesa, el reproductor muestra los datos, el video. Mientras se reproduce, seguirán llegando más datos y esperarán en el búfer.

Si el reproductor ha terminado de procesar o reproducir los datos anteriores, y el búfer aún no se ha llenado, el texto "búfer" se mostrará nuevamente, esperando reunir más datos para procesar.

¡Eso es Buffer!

De la definición original de un búfer, muestra que mientras estamos en el búfer, podemos manipular o interactuar con los datos binarios que se transmiten. ¿Qué tipo de interacción podríamos tener con estos datos binarios sin procesar? La implementación de Buffer en Node.js nos proporciona una lista completa de lo que es factible. Veamos algunos de ellos.

Interactuar con un búfer

¡Incluso es posible crear su propio búfer! Aparte del que Node.js creará automáticamente durante una transmisión, es posible crear y manipular su propio búfer. Interesante verdad? ¡Creemos uno!

Dependiendo de lo que desee lograr, hay diferentes formas de crear un búfer. Veamos algunos.

// Create an empty buffer of size 10. // A buffer that only can accommodate 10 bytes.
const buf1 = Buffer.alloc(10);
// Create a buffer with content
const buf2 = Buffer.from("hello buffer");

Una vez que se haya creado su búfer, puede comenzar a interactuar con él

// Examine the structure of a buffer
buf1.toJSON()// { type: 'Buffer', data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }// an empty buffer
buf2.toJSON()// { type: 'Buffer', data: [ 104, 101, 108, 108, 111, 32, 98, 117, 102, 102, 101, 114 ] }
// the toJSON() method presents the data as the Unicode Code Points of the characters
// Examine the size of a buffer
buf1.length // 10
buf2.length // 12. Auto-assigned based on the initial content when created.
// Write to a bufferbuf1.write("Buffer really rocks!") 
// Decode a buffer
buf1.toString() // 'Buffer rea'
//oops, because buf1 is created to contain only 10 bytes, it couldn't accommodate the rest of the characters
// Compare two buffers

Hay muchas interacciones que podríamos tener con un búfer. Dirígete a los documentos oficiales para jugar más con estos métodos.

Finalmente, te dejo con este pequeño desafío: lee el código fuente de zlib.js , una de las bibliotecas centrales de Node.js, para ver cómo está aprovechando el poder del búfer para manipular flujos de datos binarios. Estos resultan ser archivos gziped. Mientras lee, documente lo que aprenda y comparta amablemente con nosotros aquí en los comentarios.

Espero que esta introducción te haya ayudado a comprender mejor el búfer de Node.js.

Si sientes que hice un buen trabajo y que otros merecen la oportunidad de ver esto, aplaude amablemente para que el artículo ayude a difundir una mejor comprensión de Buffer en nuestra comunidad de Node.js.

Si tiene una pregunta que no ha sido respondida o tiene una comprensión diferente de algunos de los puntos aquí, no dude en dejar comentarios aquí o vía Twitter.