Maison  >  Article  >  interface Web  >  Qu’est-ce qu’un tampon ? En savoir plus sur le module buffer dans Nodejs

Qu’est-ce qu’un tampon ? En savoir plus sur le module buffer dans Nodejs

青灯夜游
青灯夜游avant
2021-12-30 19:21:163035parcourir

Qu'est-ce qu'un tampon ? L'article suivant vous donnera une compréhension approfondie du module tampon dans Nodejs et présentera les méthodes de création, de copie, d'épissage, d'interception, de remplissage de tampons et de conversion de tampons et de chaînes. J'espère qu'il sera utile à tout le monde. !

Qu’est-ce qu’un tampon ? En savoir plus sur le module buffer dans Nodejs

1. Qu'est-ce qu'un tampon ?

Nous savons que JS a des API de méthodes correspondantes pour exploiter les chaînes, les tableaux, les nombres, les valeurs booléennes, etc., et dans Node, il nécessite également des opérations sur les fichiers, des communications réseau, des opérations de base de données, la transmission de données et d'autres capacités de stockage de fichiers ; Au niveau, ils sont tous exprimés sous forme binaire. La transmission des données dans les requêtes et réponses HTTP est également transmise sous forme de données binaires, donc les capacités JS actuelles ne suffisent pas à elles seules, le module tampon est donc fourni dans Node.

C'est-à-dire donner à NodeJS la possibilité de manipuler des données binaires comme des chaînes. Le tampon est également appelé zone de stockage temporaire, qui est une section de mémoire qui stocke temporairement les données binaires d'entrée et de sortie. 临时性暂存区,即临时存放输入和输出二进制数据的一段内存。

在之前的一篇文章聊聊Nodejs中的核心模块:stream流模块(看看如何使用)中,我们了解到在对大文件进行读取操作时候,一般不会一次性全部读取到内存中,而是以流的形式读取一段数据块,而连续的数据块便形成了数据流的概念。而在对数据块读取和写入过程中,数据首先会存储在buffer(临时性暂存区)的内存中,以待被处理。

1.1 了解buffer内存分配

buffer对象的内存分配并不是在V8的堆内存中,而是在Node的C++层面实现内存的申请;为了高效的使用申请来得内存,Node中采用slab分配机制(一种动态内存管理机制)。

1. 2 buffer的全局性

Node在进程启动时buffer就已经加装进入内存,并将其放入全局对象,使用时候可以无需require引入,但是官方但仍然建议通过 import 或 require 语句显式地引用它。

2. 创建Buffer

buffer实例除了可以在文件读取,http请求得到之外,还可以通过手动方式构造创建。

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

参数:

  • size: buffer长度
  • fill: 预填充值,默认值:0
  • encoding: 如果fill是字符串,则就是字符串的编码,默认:utf-8
import { Buffer } from 'buffer';

const buf = Buffer.alloc(8);

console.log(buf);
// <Buffer 00 00 00 00 00 00 00 00>

2.2 Buffer.allocUnsafe(size)

参数:

  • size: 新的buffer所需要长度
  • 以这种方式创建的 Buffer 实例的底层内存不会被初始化。 新创建的 Buffer 的内容是未知的,可能包含敏感的数据。
import { Buffer } from &#39;buffer&#39;;

const buf = Buffer.allocUnsafe(8);

console.log(buf);
// <Buffer e8 bf 99 e6 98 af e4 b8 80 e6>

2.3 Buffer.from(string[, encoding])

创建包含传入string的新buffer

参数:

  • string: 字符串
  • encoding: 编码,默认值:utf-8
import { Buffer } from &#39;buffer&#39;;

const buf = Buffer.from(&#39;hello buffer&#39;);

console.log(buf);
// <Buffer 68 65 6c 6c 6f 20 62 75 66 66 65 72>

2.4 Buffer.from(array)

使用 0 – 255 范围内的字节 array 分配新的 Buffer

import { Buffer } from &#39;buffer&#39;;

const array = [0x62, 0x78, 0x84];
const buf = Buffer.from(array);

console.log(buf);
// <Buffer 62 78 84>

3. 复制Buffer

3.1 Buffer.from(buffer)

参数:

  • buffer,要复制的buffer实例
import { Buffer } from &#39;buffer&#39;;
// 新建
const buf1 = Buffer.alloc(10, 2);
// 复制
const buf2 = Buffer.from(buf1);

console.log(buf1);
// <Buffer 02 02 02 02 02 02 02 02 02 02>
console.log(buf2);
// <Buffer 02 02 02 02 02 02 02 02 02 02>

3.2 buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])

将buf实例复制到target目标

import { Buffer } from &#39;buffer&#39;;

const buf1 = Buffer.alloc(10, 2);
const buf2 = Buffer.allocUnsafe(10)
// 将buf1复制到buf2
buf1.copy(buf2);

console.log(buf1);
// <Buffer 02 02 02 02 02 02 02 02 02 02>
console.log(buf2);
// <Buffer 02 02 02 02 02 02 02 02 02 02>

4. 拼接Buffer

4.1 Buffer.concat(list[, totalLength])

返回list中所有buffer实例连接在一起的新buffer

参数:

  • list:ce1f03efdfa3a50760234dcf9b3662a8 | 2352a1ddeafcbb075c98dd9a641f874c
  • totalLength: 连接总长度。

注意

Dans un article précédent Parlons du module principal de Nodejs : le module stream (voir Voir comment à utiliser)
    , nous avons appris que lors de la lecture d'un gros fichier, il n'est généralement pas lu d'un seul coup dans la mémoire, mais un bloc de données est lu sous la forme d'un flux, et le bloc de données continu est Le concept de flux de données a été formé. Pendant le processus de lecture et d'écriture des blocs de données, les données seront d'abord stockées dans la mémoire du tampon (zone de stockage temporaire) pour être traitées.
  • 1.1 Comprendre l'allocation de mémoire tampon

L'allocation de mémoire de l'objet tampon n'est pas dans la mémoire tas du V8, mais l'application mémoire est implémentée au niveau C++ de Node afin d'utiliser efficacement la mémoire de l'application ; , Node adopte un mécanisme d'allocation de dalle (un mécanisme de gestion dynamique de la mémoire).

1.2 La nature globale du tampon

Le nœud a déjà installé le tampon dans la mémoire au démarrage du processus et le place dans l'objet global. Il peut être introduit sans besoin lors de son utilisation, mais le. officiel recommande toujours de l'importer ou d'exiger une déclaration pour y faire référence explicitement.

2. Créer un tampon🎜🎜🎜En plus de lire des fichiers et d'obtenir des requêtes http, les instances de tampon peuvent également être construites et créées manuellement. 🎜🎜🎜🎜2.1 Buffer.alloc(size[, fill[, encoding]])🎜🎜🎜🎜Paramètres : 🎜🎜🎜size : longueur du tampon 🎜🎜fill : valeur pré-remplie, valeur par défaut : 0🎜🎜encoding : if fill est une chaîne, c'est l'encodage de la chaîne Par défaut : utf-8🎜🎜
import { Buffer } from &#39;buffer&#39;;

const buf1 = Buffer.alloc(4, 2);
const buf2 = Buffer.alloc(4, 3);

const buf3 = Buffer.concat([buf1, buf2]);

console.log(buf1); // <Buffer 02 02 02 02>
console.log(buf2); // <Buffer 03 03 03 03>
console.log(buf3); // <Buffer 02 02 02 02 03 03 03 03>
🎜🎜🎜2.2 Buffer.allocUnsafe(size)🎜🎜🎜🎜Paramètres : 🎜🎜🎜size : La longueur requise du nouveau tampon🎜. 🎜 est basé sur ceci. La mémoire sous-jacente des instances Buffer créées de cette manière ne sera pas initialisée. Le contenu du Buffer nouvellement créé est inconnu et peut contenir des données sensibles. 🎜🎜
import { Buffer } from &#39;buffer&#39;;

const buf1 = Buffer.alloc(10, 2);
// 截取
const buf2 = buf1.slice(1,4);
// 截取部分修改
buf2[0] = 0x63;

console.log(buf1);
// <Buffer 02 63 02 02 02 02 02 02 02 02>
console.log(buf2);
// <Buffer 63 02 02>
🎜🎜🎜2.3 Buffer.from(string[, encoding])🎜🎜🎜🎜Créer un nouveau tampon contenant la chaîne entrante🎜🎜Paramètres : 🎜🎜🎜string: string 🎜🎜encoding: encoding, valeur par défaut: utf - 8🎜🎜
import { Buffer } from &#39;buffer&#39;;

const buf1 = Buffer.allocUnsafe(8).fill(2);

console.log(buf1);
// <Buffer 02 02 02 02 02 02 02 02>
🎜🎜🎜2.4 Buffer.from(array)🎜🎜🎜🎜Utiliser des octets dans la plage de 0255 array Allouer un nouveau Buffer. 🎜
import { Buffer } from &#39;buffer&#39;;
// buf1 length为12
const buf1 = Buffer.alloc(12, 3);
// write offset大于buf1.length,写入无效
buf1.write(&#39;hello&#39;, 12);

console.log(buf1);
// <Buffer 03 03 03 03 03 03 03 03 03 03 03 03>
// 部分写入
buf1.write(&#39;hello&#39;, 10);
// <Buffer 03 03 03 03 03 03 03 03 03 03 68 65>
🎜🎜3. Copy Buffer🎜🎜🎜🎜🎜3.1 Buffer.from(buffer)🎜🎜🎜🎜Paramètres : 🎜🎜🎜buffer, l'instance de tampon à copier🎜🎜
import { Buffer } from &#39;buffer&#39;;

const buf1 = Buffer.alloc(12, 3);

console.log(Buffer.isBuffer(buf1));
// true
🎜🎜🎜3. 2 buf.copy (cible[ , targetStart[, sourceStart[, sourceEnd]]])🎜🎜🎜🎜Copiez l'instance buf dans la cible cible🎜
import { Buffer } from &#39;buffer&#39;;

console.log(Buffer.isEncoding(&#39;utf-8&#39;))
// true
🎜🎜4. Splice Buffer🎜🎜🎜🎜🎜4.1 Buffer.concat(list[, totalLength])🎜🎜 🎜🎜 Renvoie un nouveau tampon dans lequel toutes les instances de tampon de la liste sont connectées ensemble. 🎜🎜🎜Remarque : 🎜🎜🎜Si la liste ne contient aucune entrée ou si totalLength est 0, un nouveau tampon de longueur nulle est renvoyé. 🎜🎜Si totalLength n'est pas fourni, il est calculé à partir des instances Buffer de la liste en ajoutant leurs longueurs. 🎜🎜
import { Buffer } from &#39;buffer&#39;;

const buf1 = Buffer.allocUnsafe(26)

for (let i = 0; i < 26; i++) {
  // 97 是 &#39;a&#39; 的十进制 ASCII 值。
  buf1[i] = i + 97;
}

console.log(buf1.toString())
// abcdefghijklmnopqrstuvwxyz
🎜🎜5. Intercept Buffer🎜🎜🎜🎜🎜5.1 buf.slice([start[, end]])🎜🎜🎜🎜Renvoyer une nouvelle instance Buffer à partir de l'instance buf La nouvelle instance Buffer renvoyée n'est que la source. buf instance Reference, c'est-à-dire que les modifications apportées à l'instance nouvellement renvoyée affecteront l'instance Buffer d'origine🎜🎜Paramètres :🎜
  • start: 起始位置,默认0
  • end: 结束位置,默认buf.length
import { Buffer } from &#39;buffer&#39;;

const buf1 = Buffer.alloc(10, 2);
// 截取
const buf2 = buf1.slice(1,4);
// 截取部分修改
buf2[0] = 0x63;

console.log(buf1);
// <Buffer 02 63 02 02 02 02 02 02 02 02>
console.log(buf2);
// <Buffer 63 02 02>

6. 填充Buffer

6.1 buf.fill(value[, offset[, end]][, encoding])

参数:

  • value,填充值
  • offset: 在开始填充 buf 之前要跳过的字节数,默认值0
  • end: 结束填充buf(不包括在内)的位置,默认值buf.length
  • encoding,如果value值为字符串,则为字符串编码,默认utf-8
import { Buffer } from &#39;buffer&#39;;

const buf1 = Buffer.allocUnsafe(8).fill(2);

console.log(buf1);
// <Buffer 02 02 02 02 02 02 02 02>

6.2 buf.write(string[, offset[, length]][, encoding])

根据 encoding 中的字符编码将 string 写入 buf 的 offset 处。

注意:length 参数是要写入的字节数。 如果 buf 没有足够的空间来容纳整个字符串,则只会写入 string 的一部分

参数:

  • string: 写入的字符串值
  • offset: 开始写入 string 之前要跳过的字节数,默认值为0
  • length: 写入的最大字节数,默认值buf.length - offset
  • encoding: 编码,默认utf-8
import { Buffer } from &#39;buffer&#39;;
// buf1 length为12
const buf1 = Buffer.alloc(12, 3);
// write offset大于buf1.length,写入无效
buf1.write(&#39;hello&#39;, 12);

console.log(buf1);
// <Buffer 03 03 03 03 03 03 03 03 03 03 03 03>
// 部分写入
buf1.write(&#39;hello&#39;, 10);
// <Buffer 03 03 03 03 03 03 03 03 03 03 68 65>

7. Buffer工具方法

7.1 Buffer.isBuffer(obj)

检验传入obj是否为buffer

import { Buffer } from &#39;buffer&#39;;

const buf1 = Buffer.alloc(12, 3);

console.log(Buffer.isBuffer(buf1));
// true

7.2 Buffer.isEncoding(encoding)

检查传入的编码名称是否被Buffer所支持

import { Buffer } from &#39;buffer&#39;;

console.log(Buffer.isEncoding(&#39;utf-8&#39;))
// true

8. Buffer与String的转换

Buffer转String

8.1 buf.toString([encoding[, start[, end]]])

参数:

  • encoding:使用的字符串编码,默认utf-8
  • start,开始位置,默认0
  • end,结束位置,默认buf.length
import { Buffer } from &#39;buffer&#39;;

const buf1 = Buffer.allocUnsafe(26)

for (let i = 0; i < 26; i++) {
  // 97 是 &#39;a&#39; 的十进制 ASCII 值。
  buf1[i] = i + 97;
}

console.log(buf1.toString())
// abcdefghijklmnopqrstuvwxyz

String转Buffer

8.2 Buffer.from(string[, encoding])

参数:

  • string: 字符串
  • encoding: 编码,默认值:utf-8
import { Buffer } from &#39;buffer&#39;;

const buf = Buffer.from(&#39;hello buffer&#39;);

console.log(buf);
// <Buffer 68 65 6c 6c 6f 20 62 75 66 66 65 72>

9. Buffer与Array的对比

9.1 与Array类似点

  • 可以使用下标获取指定位置的值
  • 可以使用length属性获取Buffer大小
  • 可以使用for...of遍历

9.2 与Array不同之处

  • 存储的是16进制的两位数
  • 值为0-255
  • 支持多种编码格式
  • 内存不在v8堆中分配
  • 底层有c++实现,上层由js控制

更多node相关知识,请访问: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