Maison >interface Web >js tutoriel >Explication détaillée de l'utilisation du tampon Node.js
Cette fois, je vous apporte une explication détaillée de l'utilisation de Node.js Buffer, et quelles sont les précautions lors de l'utilisation de Node.js Buffer. Ce qui suit est un cas pratique. , jetons un coup d'oeil.
Qu'est-ce que Buffer ?
Buffer existe en tant qu'objet global et peut être utilisé sans introduire de module. Vous ne devez pas l'ignorer.
On peut comprendre que Buffer est une zone ouverte en mémoire pour stocker des données binaires. Le tampon ouvre la mémoire hors tas.
Quels sont les scénarios d'application de Buffer ?
Flow
Comment comprendre le flow ? Le flux est une collection de données (similaire aux données, String), mais les données du flux ne peuvent pas être obtenues en une seule fois et les données ne seront pas toutes chargées dans la mémoire. Par conséquent, le flux est. très approprié pour le traitement du Big Data et les retours intermittents. La source externe du chunk. La vitesse entre les producteurs de flux et les consommateurs est généralement incohérente, des tampons sont donc nécessaires pour stocker temporairement certaines données. La taille du tampon est spécifiée par le paramètre highWaterMark, qui est de 16 Ko par défaut.
Stockage de données qui nécessitent beaucoup de mémoire
L'espace mémoire occupé par l'objet Buffer n'est pas compté dans la limite d'espace mémoire du processus Node.js, il peut donc être utilisé pour le stockage de gros objets, mais la taille de l'objet est toujours limitée. Généralement, un système 32 bits équivaut à environ 1G et un système 64 bits à environ 2G.
Comment créer un Buffer
En plus du flux créant automatiquement un Buffer implicitement, vous pouvez également créer un Buffer manuellement comme suit :
Les données stockées dans Buffer ont été déterminées
Buffer.from(obj) // Les types pris en charge par obj string, buffer, arrayBuffer, array ou array- like object
Remarque : Buffer.from ne prend pas en charge la transmission de nombres, comme indiqué ci-dessous :
Buffer.from(1234); buffer.js:208 throw new errors.TypeError( ^ TypeError [ERR_INVALID_ARG_TYPE]: The "value" argument must not be of type number. Received type number at Function.from (buffer.js:208:11) ...
Si vous souhaitez transmettre des nombres, vous pouvez transmettre un tableau :
const buf = Buffer.from([1, 2, 3, 4]); console.log(buf); // <Buffer 01 02 03 04>
Mais ceci Il y a un problème avec cette méthode. Lorsque différentes valeurs sont stockées, les données binaires enregistrées dans le tampon seront les mêmes, comme indiqué ci-dessous :
const buf2 = Buffer.from([127, -1]); console.log(buf2); // <Buffer 7f ff> const buf3 = Buffer.from([127, 255]); console.log(buf3); // <Buffer 7f ff> console.log(buf3.equals(buf2)); // true
Lorsqu'un ensemble de nombres à enregistrer se situent tous entre 0 et 255 (readUInt8 pour lire) cette plage, ou tous se situent dans la plage de -128 à 127 (readInt8 pour lire) cette plage, alors il n'y a pas de problème, sinon c'est Il est fortement déconseillé d'utiliser Buffer.from pour enregistrer un ensemble de nombres. Parce que différentes méthodes doivent être appelées lors de la lecture de différents nombres.
Les données de stockage du tampon ne sont pas déterminées
Buffer.alloc, Buffer.allocUnsafe, Buffer.allocUnsafeSlow
Buffer.alloc will Remplit la mémoire allouée avec 0 valeurs, donc c'est plus lent que les deux derniers, mais c'est aussi plus sûr. Bien sûr, vous pouvez également utiliser l'indicateur --zero-fill-buffers pour que allocUnsafe et allocUnsafeSlow se remplissent de valeurs nulles après avoir alloué de la mémoire.
node --zero-fill-buffers index.js
Lorsque l'espace alloué est inférieur à 4 Ko, allocUnsafe découpera directement l'espace du tampon précédemment pré-alloué, de sorte que la vitesse est plus rapide que allocUnsafeSlow lorsque l'espace alloué est supérieur ou égal à. 4 Ko, il n'y a aucune différence de vitesse entre les deux.
// 分配空间等于4KB function createBuffer(fn, size) { console.time('buf-' + fn); for (var i = 0; i < 100000; i++) { Buffer[fn](size); } console.timeEnd('buf-' + fn); } createBuffer('alloc', 4096); createBuffer('allocUnsafe', 4096); createBuffer('allocUnsafeSlow', 4096); // 输出 buf-alloc: 294.002ms buf-allocUnsafe: 224.072ms buf-allocUnsafeSlow: 209.22ms
function createBuffer(fn, size) { console.time('buf-' + fn); for (var i = 0; i < 100000; i++) { Buffer[fn](size); } console.timeEnd('buf-' + fn); } createBuffer('alloc', 4095); createBuffer('allocUnsafe', 4095); createBuffer('allocUnsafeSlow', 4095); // 输出 buf-alloc: 296.965ms buf-allocUnsafe: 135.877ms buf-allocUnsafeSlow: 205.225ms
Une chose à retenir : la nouvelle méthode Buffer(xxxx) n'est plus recommandée
Utiliser Buffer
buffer to string
const buf = Buffer.from('test'); console.log(buf.toString('utf8')); // test console.log(buf.toString('utf8', 0, 2)); // te
buffer to json
const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]); console.log(buf.toJSON()); // { type: 'Buffer', data: [ 1, 2, 3, 4, 5 ] }
buffer clipping, return after clipping Le le nouveau tampon pointe vers la même mémoire que le tampon d'origine
buf.slice([start[, end]])
début position de départ
fin position de fin (ne contient pas )
Exemple :
var buf1 = Buffer.from('test'); var buf2 = buf1.slice(1, 3).fill('xx'); console.log("buf2 content: " + buf2.toString()); // xx console.log("buf1 content: " + buf1.toString()); // txxt
copie du tampon, le tampon est différent du tableau, la longueur du tampon ne changera pas une fois déterminée, donc lorsque la source copiée le tampon est plus grand que Lorsque le tampon cible est grand, seule une partie de la valeur
buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])
sera copiée Exemple :
var buf1 = Buffer.from('abcdefghijkl'); var buf2 = Buffer.from('ABCDEF'); buf1.copy(buf2, 1); console.log(buf2.toString()); //Abcdef
Jugement d'égalité du tampon, la comparaison est. la valeur binaire
buf.equals(otherBuffer)
Exemple :
const buf1 = Buffer.from('ABC'); const buf2 = Buffer.from('414243', 'hex'); console.log(buf1.equals(buf2)); // true
En plus des égaux, comparer peut également être utilisé pour déterminer s'ils sont égaux (lorsque le résultat est 0, ils sont égaux), mais la fonction principale de compare est de comparer dans le tri des instances de tampon de tableau.
Si le tampon contient une valeur spécifique
buf.includes(value[, byteOffset][, encoding]) buf.indexOf(value[, byteOffset][, encoding])
示例:
const buf = Buffer.from('this is a buffer'); console.log(buf.includes('this')); // true console.log(buf.indexOf('this')); // 0
写入读取数值
写入方法:
位数固定且超过1个字节的: write{Double| Float | Int16 | Int32| UInt16 | UInt32 }{BE|LE}(value, offset)
位数不固定的: write{Int | UInt}{BE | LE}(value, offset, bytelength) //此方法提供了更灵活的位数表示数据(比如3位、5位)
位数固定是1个字节的: write{Int8 | Unit8}(value, offset)
读取方法:
位数固定且超过1个字节的: read{Double| Float | Int16 | Int32 | UInt16 | UInt32 }{BE|LE}(offset)
位数不固定的: read{Int | UInt}{BE | LE}(offset, byteLength)
位数固定是1个字节的: read{Int8 | Unit8}(offset)
Double、Float、Int16、Int32、UInt16、UInt32既确定了表征数字的位数,也确定了是否包含负数,因此定义了不同的数据范围。同时由于表征数字的位数都超过8位,无法用一个字节来表示,因此就涉及到了计算机的字节序区分(大端字节序与小端字节序)
关于大端小端的区别可以这么理解:数值的高位在buffer的起始位置的是大端,数值的低位buffer的起始位置则是小端
const buf = Buffer.allocUnsafe(2); buf.writeInt16BE(256, 0) console.log(buf); // <Buffer 01 00> buf.writeInt16LE(256, 0) console.log(buf); // <Buffer 00 01>
http://tools.jb51.net/transcoding/hexconvert这里可以查看数值的不同进制之间的转换,如果是大端的话,则直接按顺序(0100)拼接16进制即可,如果是小端则需要调换一下顺序才是正确的表示方式。
buffer合并
Buffer.concat(list[, totalLength]) //totalLength不是必须的,如果不提供的话会为了计算totalLength会多一次遍历
const buf1 = Buffer.from('this is'); const buf2 = Buffer.from(' funny'); console.log(Buffer.concat([buf1, buf2], buf1.length + buf2.length)); // <Buffer 74 68 69 73 20 69 73 20 66 75 6e 6e 79>
清空buffer
清空buffer数据最快的办法是buffer.fill(0)
buffer模块与Buffer的关系
Buffer是全局global上的一个引用,指向的其实是buffer.Buffer
const buffer = require('buffer'); console.log(buffer.Buffer === Buffer); //true
buffer模块上还有其他一些属性和方法
const buffer = require('buffer'); console.log(buffer); { Buffer: { [Function: Buffer] poolSize: 8192, from: [Function: from], alloc: [Function: alloc], allocUnsafe: [Function: allocUnsafe], allocUnsafeSlow: [Function: allocUnsafeSlow], isBuffer: [Function: isBuffer], compare: [Function: compare], isEncoding: [Function: isEncoding], concat: [Function: concat], byteLength: [Function: byteLength], [Symbol(node.isEncoding)]: [Function: isEncoding] }, SlowBuffer: [Function: SlowBuffer], transcode: [Function: transcode], INSPECT_MAX_BYTES: 50, kMaxLength: 2147483647, kStringMaxLength: 1073741799, constants: { MAX_LENGTH: 2147483647, MAX_STRING_LENGTH: 1073741799 } }
上面的kMaxLength与MAX_LENGTH代表了新建buffer时内存大小的最大值,当超过限制值后就会报错
32为机器上是(2^30)-1(~1GB)
64位机器上是(2^31)-1(~2GB)
Buffer释放
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
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!