Maison  >  Article  >  interface Web  >  En savoir plus sur les tampons dans Node

En savoir plus sur les tampons dans Node

青灯夜游
青灯夜游avant
2023-04-25 19:49:112173parcourir

En savoir plus sur les tampons dans Node

À la fin du chapitre Stream, nous nous retrouvons avec une question : quel est le morceau généré par le code suivant ?

En savoir plus sur les tampons dans Node

En imprimant, nous constatons que chunk est un objet Buffer dont les éléments sont des nombres hexadécimaux à deux chiffres, c'est-à-dire des valeurs de 0 à 255. [Recommandations de tutoriel associées : tutoriel vidéo Nodejs, Enseignement de la programmation]

Untitled 1.png

explique que les données circulant dans le Stream sont le Buffer, explorons donc le vrai visage du Buffer !

 ? Pourquoi Buffer est-il introduit dans Node ?

Au début, JS ne fonctionnait que du côté du navigateur. Il était facile de traiter les chaînes codées en Unicode, mais il était difficile de traiter les chaînes codées en binaire et non Unicode. . Et le binaire est le format de données de niveau le plus bas de l'ordinateur. Les paquets vidéo/audio/programme/réseau sont tous stockés en binaire. Node doit donc introduire un objet pour faire fonctionner le binaire, c'est pourquoi Buffer est né, qui est utilisé pour le flux/système de fichiers TCP et d'autres opérations pour traiter les octets binaires.

Comme Buffer est trop couramment utilisé dans Node, Buffer a été introduit au démarrage de Node. Il n'est pas nécessaire d'utiliser require()

Qu'est-ce qu'ArrayBuffer

ArrayBuffer est un morceau de données binaires dans la mémoire et ne peut pas fonctionner. la mémoire elle-même, doit être exploitée via un Objet TypedArray ou DataView. Représentez les données dans le tampon dans un format spécifique, et lisez et écrivez le contenu du tampon via ces formats. Il déploie une interface de tableau et peut utiliser des tableaux pour manipuler les données

Vue TypedArray

La plus couramment utilisée est la vue TypeArray. , utilisé pour lire et écrire des types simples d'ArrayBuffer, tels que la vue tableau Uint8Array (entier non signé de 8 bits), la vue tableau Int16Array (entier 16 bits)

La relation entre

et Buffer

La classe Buffer dans NodeJS est en fait l'implémentation de Uint8Array.

Structure du tampon

Buffer est un objet similaire à Array, mais il est principalement utilisé pour faire fonctionner les octets

Structure du moduleUntitled 2.png

Buffer est un module qui combine JS et C++ La partie performance est implémentée en C++, et la partie non-. La partie performance est entièrement JS. La mémoire occupée par le

Buffer implémenté n'est pas allouée par V8 et appartient à la mémoire hors tas.

Structure de l'objet

L'objet Buffer est similaire à un tableau, ses éléments sont des nombres hexadécimaux à deux chiffres, c'est-à-dire des valeurs de 0 à 255Untitled 3.png

Comme le montre cet exemple, les octets occupés par différents caractères dans le tampon sont différents, sous l'encodage UTF-8, le chinois occupe 3 octets, l'anglais et les symboles demi-largeur occupent 1 octet

Que se passera-t-il si l'élément d'entrée est un nombre décimal/négatif/dépasse 255 ? ?

Untitled 4.png

    Pour la situation ci-dessus, le traitement de Buffer est :
  • Si la valeur attribuée à l'élément est inférieure à 0, ajoutez 256 à la valeur un par un jusqu'à obtenir un entier compris entre 0 et 255
  • Si vous obtenez Si la valeur est supérieure à 255, soustrayez simplement 256 un par un jusqu'à obtenir une valeur comprise entre 0 et 255
S'il s'agit d'une décimale, seule la partie entière est conservée

Pourquoi le système hexadécimal affiché dans le Buffer

en fait toujours stocké dans la mémoire. Il s'agit d'un nombre binaire, mais Buffer utilise l'hexadécimal lors de l'affichage des données de la mémoire. La taille du tampon est de 2 octets, avec un total de 16 bits. création de 00000001 00100011,如果直接这样显示不太方便就转成为了16进制<buffer></buffer>

Buffer

Buffer.alloc et Buffer.allocUnsafe

Créer un buffer de taille fixe

Buffer.alloc(size [, fill [, encoding]])

  • size La longueur requise du nouveau Buffer
  • fill La valeur utilisée pour préremplir le nouveau Buffer. Par défaut : 0
  • encoding Si fill est une chaîne, il s'agit de son encodage de caractères. Valeur par défaut : utf8

Untitled 5.png

Buffer.allocUnsafe(size)

Alloue un tampon de taille en octets. allocUnsafe s'exécute plus rapidement que alloc. Nous avons constaté que ses résultats ne sont pas initialisés à 00 comme Buffer.alloc.

Le segment de mémoire alloué lors de l'appel de allocUnsafe n'a pas été initialisé, la vitesse d'allocation de mémoire est donc très lente, mais le segment de mémoire alloué peut contenir d'anciennes données. Si ces anciennes données ne sont pas écrasées lors de l'utilisation, des fuites de mémoire peuvent survenir. Bien que ce soit rapide, essayez d'éviter de l'utiliser. Le module Buffer pré-allouera une instance Buffer interne d'une taille de Buffer.poolSize comme pool de mémoire à allocation rapide. . Utilisez Utilisez allocUnsafe pour créer une nouvelle instance de Buffer

Untitled 6.pngBuffer.from

Créez un Buffer directement basé sur le contenu

Buffer.from(string [, encoding])

Buffer.from(array)

Buffer. from(buffer)
  • Mécanisme de mémoire de Buffer.allocUnsafe
Afin d'utiliser efficacement la mémoire demandée, Node.js adopte le mécanisme slab pour la pré-application et la post-allocation, qui est un mécanisme de gestion dynamique

Untitled 7.png Utilisez Buffer.alloc(size ) Le passage d'une taille spécifiée s'appliquera à une zone mémoire de taille fixe. La dalle a les trois états suivants : complet : état entièrement alloué

partiel : état partiellement alloué

vide : état non alloué.

Node .js utilise 8 Ko comme limite pour distinguer les petits objets des gros objets. La taille du Buffer est déterminée lors de sa création et ne peut pas être ajustée !
  • Allouer de petits objets
  • Si l'objet alloué fait moins de 8 Ko, Node l'attribuera en tant que petit objet
  • Le processus d'allocation de tampon utilise principalement un pool de variables locales comme objet de traitement intermédiaire et l'unité de dalle dans l'état d'allocation Tout le souligne. Ce qui suit est l'opération d'allocation d'une nouvelle unité de dalle, qui pointera vers elle l'objet SlowBuffer nouvellement appliqué

Untitled 8.pngUne unité de dalle

Allouer un tampon de 2 Ko

Après avoir créé un tampon de 2 Ko, une La dalle la mémoire de l'unité est la suivante :

Ce processus d'allocation est complété par la méthode d'allocation Untitled 9.png

Après avoir créé un tampon de 2 Ko, l'état actuel de la dalle est partielUntitled 10.png

Lorsque nous créerons à nouveau le tampon, nous jugerons le courant Si l'espace restant de la dalle est suffisant. Si cela est suffisant, utilisez l'espace restant et mettez à jour l'état d'allocation de la dalle

Si l'espace de la dalle n'est pas suffisant, une nouvelle dalle sera construite et l'espace restant dans la dalle d'origine sera gaspillé

Allocation de gros objets

Untitled 11.png S'il y a un tampon dépassant 8 Ko, il ira directement à la fonction creatUnsafeBuffer et allouera une unité de dalle qui sera exclusivement occupée par ce grand objet Buffer. Le mécanisme d'allocation d'allocation est comme indiqué dans la figure. Le mécanisme de Buffer est tel qu'illustré dans la figure. En utilisant le codage de caractères, les instances de Buffer et les chaînes JavaScript peuvent être converties les unes vers les autres

.

Node prend actuellement en charge huit méthodes d'encodage : utf8, ucs2, utf16le, latin1, ascii, base64, hex et base64Url Implémentation spécifique

Untitled 16.png

Une série d'API sera implémentée pour chaque schéma d'encodage différent. différents résultats renvoyés. Node.js renverra différents objets en fonction de l'encodage entrant

Conversion de Buffer et de string

String en Buffer

Principalement via la méthode Buffer.from mentionnée ci-dessus, l'encodage par défaut La méthode est utf-8

Buffer pour convertir la chaîne

Untitled 17.png

Pourquoi y a-t-il des caractères tronqués ? Comment résoudre ce problème ?

En termes de lecture, la longueur de chaque lecture est de 4 et la sortie du bloc est la suivante

Untitled 18.png

Pourdata += chunk等价于data = data.toString + chunk.toString

Puisqu'un caractère chinois occupe trois octets, le quatrième du premier bloc Les octets s'afficheront des caractères tronqués, et les premier et deuxième octets du deuxième morceau ne peuvent pas former de texte, etc., donc des caractères tronqués apparaîtront. Pour plus de connaissances sur les nœuds, veuillez visiter :

tutoriel Nodejs

 !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer