Voulez-vous une meilleure compréhension de Buffer dans Node.js? Regarde ça.

Êtes-vous toujours perplexe, comme moi, chaque fois que vous rencontrez des mots comme Buffer, Stream et des données binaires dansNode.js? Est-ce que ce sentiment vous fait hésiter à les comprendre, pensant qu'ils ne sont pas destinés à vous mais uniquement aux gourous de Node.js et aux développeurs de packages à comprendre?

En effet, ces mots pourraient être très intimidants, surtout lorsque vous entrez dans le développement Web avec Node.js sans aucun diplôme CS.

Malheureusement, de nombreux didacticiels et livres passeront directement à l'enseignement du développement d'applications Web avec les packages Node.js sans vous permettre de comprendre les fonctionnalités de base de Node.js et pourquoi elles existent. Et certains vous diront effrontément que vous n'avez pas besoin de les comprendre parce que vouspourrait ne jamais travailler avec eux directement.

Eh bien, c'est vrai, vous pourriez ne jamais travailler avec eux directement si vous choisissez de rester un développeur Node.js moyen.

Cependant, si les mystères vous rendent vraiment curieux et que vous ne reculerez devant rien pour satisfaire votre curiosité, et si vous voulez faire passer votre compréhension de Node.js au niveau suivant, alors vous voulez vraiment creuser plus profondément pour comprendre les nombreuses fonctionnalités de base. de Node.js, comme Buffer , par exemple. Et c'est exactement pourquoi j'écris cet article - pour nous aider à démystifier certaines de ces fonctionnalités et à faire passer notre apprentissage Node.js au niveau supérieur.

Lors de l'introduction de Buffer , la documentation officielle de Node.js indique en partie…

… Mécanisme de lecture ou de manipulation de flux de données binaires. La Bufferclasse a été introduite dans le cadre de l'API Node.js pour permettre d'interagir avec les flux d'octets dans le contexte de choses comme les flux TCP et les opérations du système de fichiers.

Hmmm, à moins d'avoir une connaissance préalable de tous les mots des phrases ci-dessus, ce ne sont probablement qu'un tas de jargon. Essayons de simplifier un peu cela en le reformulant, afin que nous puissions avoir une concentration claire et ne pas être distraits par les nombreuses cloches et sifflets qui s'y trouvent. Extrait de cette introduction, nous pourrions dire en toute sécurité:

La Bufferclasse a été introduite dans le cadre de l'API Node.js pour permettre de manipuler ou d'interagir avec des flux de données binaires.

Maintenant c'est plus simple, non? Mais… Tampon, flux, données binaires… encore beaucoup de gros mots. Eh bien, essayons d'aborder ces grands mots du dernier au premier.

Les données binaires, qu'est-ce que c'est?

Vous savez probablement déjà que les ordinateurs stockent et représentent les données dans des binaires. Le binaire est simplement un ensemble ou une collection de 1 et de 0. Par exemple, voici cinq binaires différents, cinq ensembles différents de 1 et de 0:

10, 01, 001, 1110,00101011

Chaque nombre dans un binaire, chacun 1et 0dans un ensemble est appelé un bit , qui est une forme abrégée de chiffre binaire.

Pour stocker ou représenter un élément de données, un ordinateur doit convertir ces données en sa représentation binaire. Par exemple, pour stocker le nombre 12, un ordinateur doit convertir 12 en sa représentation binaire qui est 1100.

Comment un ordinateur sait-il comment effectuer cette conversion? Eh bien, ce sont des mathématiques pures. C'est le système numérique binaire simple que nous avons appris en mathématiques de base - exprimant un nombre dans le système numérique en base 2. Les ordinateurs comprennent ces mathématiques.

Mais les nombres ne sont pas le seul type de données avec lequel nous travaillons. Nous avons également des chaînes, des images et même des vidéos. Les ordinateurs savent représenter tous les types de données dans des binaires. Prenons des chaînes, par exemple. Comment un ordinateur représentera-t-il la chaîne «L» dans les binaires? Pour stocker n'importe quel caractère dans des binaires, les ordinateurs convertissent d'abord ce caractère en nombre, puis convertissent ce nombre en sa représentation binaire. Donc pour la chaîne «L»,les ordinateurs seront d' abord convertir L à un nombre qui représente L . Voyons comment.

Ouvrez votre console de navigateur et collez l'extrait de code suivant puis appuyez sur Entrée: "L".charCodeAt(0). Qu'as-tu vu? Le nombre 76? Telle est la représentation des nombres ou caractères code ou Code Point du caractère L . Mais comment un ordinateur sait-il quel nombre exact représentera chaque caractère? Comment sait-il utiliser le nombre 76 pour représenter L ?

Jeux de caractères

Les jeux de caractères sont des règles déjà définies sur le nombre exact représentant chaque caractère. Nous avons différentes définitions de ces règles, les plus populaires étant l' Unicode et ASCII . JavaScript fonctionne très bien avec les jeux de caractères Unicode. En fait, il est l'Unicode dans votre navigateur que les États qui devraient représenter 76 L .

Nous avons donc vu comment les ordinateurs représentent les caractères en nombres. Maintenant, l'ordinateur représentera à son tour le nombre 76 dans sa représentation binaire. Vous pourriez penser, eh bien, convertissez simplement 76 en système numérique de base 2. Pas si vite!

Encodage de caractère

Tout comme il existe des règles qui définissent le nombre qui doit représenter un caractère, il existe également des règles qui définissent comment ce nombre doit être représenté dans les binaires. Plus précisément, combien de bits utiliser pour représenter le nombre. C'est ce qu'on appelle le codage des caractères .

L'une des définitions du codage de caractères est l' UTF-8 . UTF-8 indique que les caractères doivent être encodés en octets. Un octet est un ensemble de huit bits - huit 1 et 0. Ainsi, huit 1 et 0 doivent être utilisés pour représenter le point de code de n'importe quel caractère en binaire.

Pour comprendre cela, comme nous l'avons mentionné précédemment, la représentation binaire du nombre 12 est 1100. Ainsi, lorsque UTF-8 déclare que 12 devrait être sur huit bits, UTF-8 dit qu'un ordinateur doit ajouter plus de bits sur le côté gauche de la représentation en base 2 réelle du nombre 12 pour en faire un octet. Donc, 12 devrait être stocké comme 00001100. Logique?

Par conséquent, 76 doit être stocké sous forme de fichiers 01001100.

Voici, mes amis, comment les ordinateurs stockent des chaînes ou des caractères dans des binaires. De même, les ordinateurs ont également spécifié des règles sur la façon dont les images et les vidéos doivent être converties ou encodées et stockées dans des binaires. Le point ici est que les ordinateurs stockent tous les types de données dans des binaires, ce que l'on appelle des données binaires.

Si vous êtes très intéressé par les détails de l'encodage de caractères, vous aimerez peut-être cette introduction douce et détaillée.

Nous comprenons maintenant ce que sont les données binaires, mais que sont les flux de données binairesde notre introduction au tampon?

Courant

Stream dans Node.js signifie simplement une séquence de données déplacée d'un point à l'autre au fil du temps. Tout le concept est que vous avez une énorme quantité de données à traiter, mais vous n'avez pas besoin d'attendre que toutes les données soient disponibles avant de commencer à les traiter.

Fondamentalement, ces données volumineuses sont décomposées et envoyées en morceaux. Donc, à partir de la définition originale d'un tampon («flux de données binaires… dans le contexte de… système de fichiers»), cela signifie simplement que des données binaires sont déplacées dans le système de fichiers. Par exemple, déplacer les textes stockés dans file1.txt vers file2.txt.

Mais comment le tampon nous aide-t-il exactement à interagir avec ou à manipuler des données binaires pendant le streaming? Quel est exactement ce tampon btw?

Tampon

Nous avons vu qu'un flux de données est le mouvement de données d'un point à un autre, mais comment sont-elles exactement déplacées?

En règle générale, le mouvement des données a généralement l'intention de les traiter ou de les lire et de prendre des décisions en fonction de celles-ci. Mais il existe un minimum et un maximum de données qu'un processus peut prendre au fil du temps. Ainsi, si la vitesse à laquelle les données arrivent est plus rapide que la vitesse à laquelle le processus consomme les données, les données en excès doivent attendre quelque part leur tour pour être traitées.

En revanche, si le processus consomme les données plus rapidement qu'elles n'arrivent, les quelques données qui arrivent plus tôt doivent attendre qu'une certaine quantité de données arrive avant d'être envoyées pour traitement.

Cette «zone d'attente » est le tampon! Il s'agit d'un petit emplacement physique dans votre ordinateur, généralement dans la RAM, où les données sont temporairement collectées, attendent et sont finalement envoyées pour traitement pendant la diffusion en continu.

Nous pouvons considérer l'ensemble du processus de flux et de tampon comme une gare routière. Dans certaines gares routières, un bus n'est pas autorisé à partir jusqu'à l'arrivée d'un certain nombre de passagers ou jusqu'à une heure de départ spécifique. En outre, les passagers peuvent arriver à des heures différentes avec des vitesses différentes. Ni les passagers ni la gare routière ne contrôlent l'arrivée des passagers à la gare.

Dans tous les cas, les passagers qui arrivent plus tôt devront attendre que la gare routière décide d'envoyer le bus en route. Alors que les passagers qui arrivent alors que le bus est déjà en cours de chargement ou lorsque le bus est déjà parti doivent attendre le prochain bus.

Quoi qu'il en soit, il y a toujours une place d'attente. C'est le tampon de Node.js! Node.js ne peut pas contrôler la vitesse ou l'heure d'arrivée des données, la vitesse du flux. Il ne peut décider que du moment de l'envoi des données. Si ce n'est pas encore l'heure, Node.js les placera dans le tampon - la «zone d'attente» - un petit emplacement dans la RAM, jusqu'à ce qu'il soit temps de les envoyer pour traitement.

Un exemple typique où vous pouvez voir le tampon en action est lorsque vous diffusez une vidéo en ligne. Si votre connexion Internet est assez rapide, la vitesse du flux sera suffisamment rapide pour remplir instantanément le tampon et l'envoyer pour traitement, puis en remplir un autre et l'envoyer, puis un autre, et encore un autre ... jusqu'au flux est fini.

Mais si votre connexion est lente, après avoir traité le premier ensemble de données arrivé, le lecteur vidéo affichera une icône de chargement, ou affichera le texte «buffering», ce qui signifie collecter plus de données, ou attendre l'arrivée de plus de données. Et lorsque la mémoire tampon est remplie et traitée, le lecteur affiche les données, la vidéo. Pendant la lecture, plus de données continueront à arriver et à attendre dans la mémoire tampon.

Si le lecteur a fini de traiter ou de lire les données précédentes et que la mémoire tampon n'est pas encore remplie, le texte «tampon» sera à nouveau affiché, en attendant de collecter plus de données à traiter.

C'est Buffer!

À partir de la définition originale d'un tampon, cela montre que, dans le tampon, nous pouvons manipuler ou interagir avec les données binaires diffusées. Quel genre d'interaction pourrions-nous avoir avec ces données binaires brutes? L'implémentation de Buffer dans Node.js nous fournit une liste complète de ce qui est faisable. Voyons certains d'entre eux.

Interagir avec un tampon

Il est même possible de créer votre propre tampon! Hormis celui que Node.js créera automatiquement pendant un flux, il est possible de créer et de manipuler votre propre tampon. Intéressant non? Créons-en un!

En fonction de ce que vous souhaitez réaliser, il existe différentes manières de créer un tampon. Voyons en voir.

// 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");

Une fois votre tampon créé, vous pouvez commencer à interagir avec lui

// 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

Il y a beaucoup d'interactions que nous pourrions avoir avec un tampon. Rendez-vous sur la documentation officielle pour jouer plus avec ces méthodes.

Enfin, je vous laisse avec ce petit défi: allez lire la source de zlib.js , l'une des bibliothèques de base de Node.js, pour voir comment elle exploite la puissance du tampon pour manipuler des flux de données binaires. Ce sont des fichiers gzipés. Pendant que vous lisez, documentez ce que vous apprenez et partagez avec nous ici dans les commentaires.

J'espère que cette introduction vous a aidé à mieux comprendre Node.js Buffer.

Si vous pensez que j'ai fait du bon travail, et que d'autres méritent d'avoir une chance de voir cela, merci de bien vouloir applaudir l'article pour aider à diffuser une meilleure compréhension de Buffer dans notre communauté Node.js.

Si vous avez une question à laquelle vous n'avez pas répondu ou si vous avez une compréhension différente de certains des points ici, n'hésitez pas à laisser des commentaires ici ou via Twitter.