摘要:是什么存在于全局對(duì)象上,無(wú)需引入模塊即可使用,可見(jiàn)重要性非同一般??梢岳斫馐窃趦?nèi)存中開(kāi)辟的一片區(qū)域,用于存放二進(jìn)制數(shù)據(jù)。大小通過(guò)參數(shù)指定,默認(rèn)情況下是。一般情況下位系統(tǒng)大約是,位系統(tǒng)大約是。
Buffer是什么?
Buffer存在于全局對(duì)象上,無(wú)需引入模塊即可使用,可見(jiàn)重要性非同一般。
可以理解Buffer是在內(nèi)存中開(kāi)辟的一片區(qū)域,用于存放二進(jìn)制數(shù)據(jù)。Buffer所開(kāi)辟的是堆外內(nèi)存。
怎么理解流呢?流是數(shù)據(jù)的集合(與數(shù)據(jù)、字符串類(lèi)似),但是流的數(shù)據(jù)不能一次性獲取到,數(shù)據(jù)也不會(huì)全部load到內(nèi)存中,因此流非常適合大數(shù)據(jù)處理以及斷斷續(xù)續(xù)返回chunk的外部源。流的生產(chǎn)者與消費(fèi)者之間的速度通常是不一致的,因此需要buffer來(lái)暫存一些數(shù)據(jù)。buffer大小通過(guò)highWaterMark參數(shù)指定,默認(rèn)情況下是16Kb。
存儲(chǔ)需要占用大量?jī)?nèi)存的數(shù)據(jù)Buffer 對(duì)象占用的內(nèi)存空間是不計(jì)算在 Node.js 進(jìn)程內(nèi)存空間限制上的,所以可以用來(lái)存儲(chǔ)大對(duì)象,但是對(duì)象的大小還是有限制的。一般情況下32位系統(tǒng)大約是1G,64位系統(tǒng)大約是2G。
如何創(chuàng)建Buffer除了流自動(dòng)隱式創(chuàng)建Buffer之外,也可以手動(dòng)創(chuàng)建Buffer,方式如下:
Buffer.from(obj) // obj支持的類(lèi)型string, buffer, arrayBuffer, array, or array-like object
注意:Buffer.from不支持傳入數(shù)字,如下所示:
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) ...
若要傳入數(shù)字可以采用傳入數(shù)組的方式:
const buf = Buffer.from([1, 2, 3, 4]); console.log(buf); //
但是這種方式存在一個(gè)問(wèn)題,當(dāng)存入不同的數(shù)值的時(shí)候buffer中記錄的二進(jìn)制數(shù)據(jù)會(huì)相同,如下所示:
const buf2 = Buffer.from([127, -1]); console.log(buf2); const buf3 = Buffer.from([127, 255]); console.log(buf3); console.log(buf3.equals(buf2)); // true
當(dāng)要記錄的一組數(shù)全部落在0到255(readUInt8來(lái)讀?。┻@個(gè)范圍, 或者全部落在-128到127(readInt8來(lái)讀?。┻@個(gè)范圍那么就沒(méi)有問(wèn)題,否則的話就強(qiáng)烈不推薦使用Buffer.from來(lái)保存一組數(shù)。因?yàn)椴煌臄?shù)字讀取時(shí)應(yīng)該調(diào)用不同的方法。
Buffer.alloc、Buffer.allocUnsafe、Buffer.allocUnsafeSlow
Buffer.alloc會(huì)用0值填充已分配的內(nèi)存,所以相比后兩者速度上要慢,但是也較為安全。當(dāng)然也可以通過(guò)--zero-fill-buffers flag使allocUnsafe、allocUnsafeSlow在分配完內(nèi)存后也進(jìn)行0值填充。
node --zero-fill-buffers index.js
當(dāng)分配的空間小于4KB的時(shí)候,allocUnsafe會(huì)直接從之前預(yù)分配的Buffer里面slice空間,因此速度比allocUnsafeSlow要快,當(dāng)大于等于4KB的時(shí)候二者速度相差無(wú)異。
// 分配空間等于 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
需要謹(jǐn)記一點(diǎn):new Buffer(xxxx) 方式已經(jīng)不推薦使用了
Buffer使用const buf = Buffer.from("test"); console.log(buf.toString("utf8")); // test console.log(buf.toString("utf8", 0, 2)); // te
const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]); console.log(buf.toJSON()); // { type: "Buffer", data: [ 1, 2, 3, 4, 5 ] }
buf.slice([start[, end]]) start 起始位置 end 結(jié)束位置(不包含) 示例: 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
buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]]) 示例: var buf1 = Buffer.from("abcdefghijkl"); var buf2 = Buffer.from("ABCDEF"); buf1.copy(buf2, 1); console.log(buf2.toString()); //Abcdef
buf.equals(otherBuffer) 示例: const buf1 = Buffer.from("ABC"); const buf2 = Buffer.from("414243", "hex"); console.log(buf1.equals(buf2)); // true
除了equals之外,compare其實(shí)也可以用于判斷是否相等(當(dāng)結(jié)果為0則相等),不過(guò)compare更主要的作用是用于對(duì)數(shù)組內(nèi)的buffer實(shí)例排序。
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
寫(xiě)入方法:
write{Double| Float | Int16 | Int32| UInt16 | UInt32 }{BE|LE}(value, offset)
write{Int | UInt}{BE | LE}(value, offset, bytelength) // 此方法提供了更靈活的位數(shù)表示數(shù)據(jù)(比如3位、5位)
write{Int8 | Unit8}(value, offset)
讀取方法:
write{Double| Float | Int16 | Int32 | UInt16 | UInt32 }{BE|LE}(offset)
read{Int | UInt}{BE | LE}(offset, byteLength)
read{Int8 | Unit8}(offset)
Double、Float、Int16、Int32、UInt16、UInt32既確定了表征數(shù)字的位數(shù),也確定了是否包含負(fù)數(shù),因此定義了不同的數(shù)據(jù)范圍。同時(shí)由于表征數(shù)字的位數(shù)都超過(guò)8位,無(wú)法用一個(gè)字節(jié)來(lái)表示,因此就涉及到了計(jì)算機(jī)的字節(jié)序區(qū)分(大端字節(jié)序與小端字節(jié)序)
關(guān)于大端小端的區(qū)別可以這么理解:數(shù)值的高位在buffer的起始位置的是大端,數(shù)值的低位buffer的起始位置則是小端
const buf = Buffer.allocUnsafe(2); buf.writeInt16BE(256, 0) console.log(buf); //buf.writeInt16LE(256, 0) console.log(buf); //
https://tool.lu/hexconvert/ 這里可以查看數(shù)值的不同進(jìn)制之間的轉(zhuǎn)換,如果是大端的話,則直接按順序(0100)拼接16進(jìn)制即可,如果是小端則需要調(diào)換一下順序才是正確的表示方式。
Buffer.concat(list[, totalLength]) //totalLength不是必須的,如果不提供的話會(huì)為了計(jì)算totalLength會(huì)多一次遍歷 const buf1 = Buffer.from("this is"); const buf2 = Buffer.from(" funny"); console.log(Buffer.concat([buf1, buf2], buf1.length + buf2.length)); //
清空buffer數(shù)據(jù)最快的辦法是buffer.fill(0)
buffer模塊與Buffer的關(guān)系Buffer是全局global上的一個(gè)引用,指向的其實(shí)是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時(shí)內(nèi)存大小的最大值,當(dāng)超過(guò)限制值后就會(huì)報(bào)錯(cuò)
32為機(jī)器上是(2^30)-1(~1GB)
64位機(jī)器上是(2^31)-1(~2GB)
Buffer釋放我們無(wú)法手動(dòng)對(duì)buffer實(shí)例進(jìn)行GC,只能依靠V8來(lái)進(jìn)行,我們唯一能做的就是解除對(duì)buffer實(shí)例的引用
參考資料http://cenalulu.github.io/lin...
http://www.ruanyifeng.com/blo...
https://medium.freecodecamp.o...
https://www.barretlee.com/blo...
https://medium.freecodecamp.o...
http://www.runoob.com/nodejs/...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95080.html
摘要:默認(rèn)情況下,會(huì)打印堆棧信息到然后退出進(jìn)程。適用于父子進(jìn)程之間發(fā)送消息,關(guān)于如何創(chuàng)建父子進(jìn)程會(huì)放在模塊中進(jìn)行。信號(hào)雖然也是用于請(qǐng)求終止進(jìn)程,但是它與有所不同,進(jìn)程可以選擇響應(yīng)還是忽略此信號(hào)。 process存在于全局對(duì)象上,不需要使用require()加載即可使用,process模塊主要做兩方面的事情 讀:獲取進(jìn)程信息(資源使用、運(yùn)行環(huán)境、運(yùn)行狀態(tài)) 寫(xiě):執(zhí)行進(jìn)程操作(監(jiān)聽(tīng)事件、調(diào)度任...
摘要:預(yù)備工作序最近正在研究相關(guān)的知識(shí),想著如何能自己實(shí)現(xiàn)協(xié)議。監(jiān)聽(tīng)事件就是協(xié)議的抽象,直接在上面監(jiān)聽(tīng)已有的事件和事件這兩個(gè)事件。表示當(dāng)前數(shù)據(jù)幀為消息的最后一個(gè)數(shù)據(jù)幀,此時(shí)接收方已經(jīng)收到完整的消息,可以對(duì)消息進(jìn)行處理。 A、預(yù)備工作 1、序 最近正在研究 Websocket 相關(guān)的知識(shí),想著如何能自己實(shí)現(xiàn) Websocket 協(xié)議。到網(wǎng)上搜羅了一番資料后用 Node.js 實(shí)現(xiàn)該協(xié)議,倒也沒(méi)...
摘要:上游水源通過(guò)里中的方法流入水電站中。當(dāng)在接收數(shù)據(jù)中出現(xiàn)錯(cuò)誤時(shí)發(fā)出。暫??勺x流,不再發(fā)出事件恢復(fù)可讀流,繼續(xù)發(fā)出事件把這個(gè)可讀流的輸出傳遞給指定的流,兩個(gè)流組成一個(gè)管道。 題外話 該文章整合了多篇網(wǎng)絡(luò)文章(整合之處已設(shè)置超鏈接,可點(diǎn)擊直接了解原文),目的僅僅是為了和大伙分享,更加通俗易懂的了解流的各個(gè)流程的初始。本人也是node的初學(xué)菜鳥(niǎo),有描述錯(cuò)誤或誤人子弟的地方多請(qǐng)大神們多多指出。 ...
摘要:回調(diào)函數(shù)提供兩個(gè)參數(shù)和,表示有沒(méi)有錯(cuò)誤發(fā)生,是文件內(nèi)容。文件關(guān)閉第一個(gè)參數(shù)文件時(shí)傳遞的文件描述符第二個(gè)參數(shù)回調(diào)函數(shù)回調(diào)函數(shù)有一個(gè)參數(shù)錯(cuò)誤,關(guān)閉文件后執(zhí)行。 showImg(//img.mukewang.com/5d3f890d0001836113660768.jpg); 人所缺乏的不是才干而是志向,不是成功的能力而是勤勞的意志。 —— 部爾衛(wèi) 文章同步到github博客:https:/...
摘要:名稱(chēng)默認(rèn)配置作用域官方說(shuō)明中文解讀模塊是否開(kāi)啟對(duì)后端的緩沖指定一個(gè)連接到代理服務(wù)器的超時(shí)時(shí)間,單位為秒,需要注意的是這個(gè)時(shí)間最好不要超過(guò)秒。 序 本文主要解析一下nginx http模塊配置參數(shù)。主要分socket相關(guān)參數(shù),對(duì)clinet請(qǐng)求的buffer參數(shù)以及對(duì)response的buffer參數(shù)。 socket 名稱(chēng) 默認(rèn)配置 作用域 官方說(shuō)明 中文解讀 模塊 sendf...
閱讀 2825·2021-11-18 10:02
閱讀 3690·2021-11-15 17:59
閱讀 2316·2021-09-06 15:00
閱讀 3353·2019-08-29 16:58
閱讀 1068·2019-08-26 10:34
閱讀 1587·2019-08-26 10:15
閱讀 1295·2019-08-26 10:11
閱讀 2728·2019-08-23 18:33