摘要:核心模塊學(xué)習(xí)之何為在引入之前,沒有能讀取和操作二進(jìn)制數(shù)據(jù)流的機(jī)制,作為引入,以便能和網(wǎng)絡(luò)流文件流等進(jìn)行交互。返回值寫入的實(shí)際大小,沒有足夠的空間保存,只會(huì)寫入一部分。返回值實(shí)際存入的字節(jié)數(shù)。參考文章一進(jìn)階核心模塊常用使用總結(jié)
node 核心模塊學(xué)習(xí)之Buffer 何為 Buffer
在ES6引入 TypeArray 之前,JS沒有能讀取和操作二進(jìn)制數(shù)據(jù)流的機(jī)制,Buffer 作為 Node API 引入,以便能和 TCP 網(wǎng)絡(luò)流、文件流等進(jìn)行交互。 目前 ES6 中有 TypeArray 了,Buffer 類以更加優(yōu)化和適用的于 Node 操作的方式實(shí)現(xiàn)了 Unit8Array API。
總之,Buffer 就是用來操作二進(jìn)制數(shù)據(jù)的,位于全局變量中,無需引入即可使用。
Buffer 實(shí)例類似于 整型數(shù)組,緩沖區(qū)大小在創(chuàng)建是確定,不能調(diào)整,內(nèi)存有C++申請(qǐng),JS 分配。
Instances of the Buffer class are similar to arrays of integers but correspond to fixed-sized, raw memory allocations outside the V8 heap. The size of the Buffer is established when it is created and cannot be changed....mechanism for reading or manipulating streams of binary data. The Buffer class was introduced as part of the Node.js API to make it possible to interact with octet streams in the context of things like TCP streams and file system operations。
Buffer 緩存區(qū),計(jì)算機(jī)讀取速度和處理不匹配,讀取速度高于處理速度時(shí),會(huì)開辟一段內(nèi)存區(qū)域存放待處理的數(shù)據(jù),這個(gè)段內(nèi)存就叫緩沖區(qū)。
實(shí)例化 Buffer在v6.0之前創(chuàng)建Buffer對(duì)象直接使用new Buffer()構(gòu)造函數(shù)來創(chuàng)建對(duì)象實(shí)例,但是Buffer對(duì)內(nèi)存的權(quán)限操作相比很大,可以直接捕獲一些敏感信息,存在安全隱患,之后的版本,用下面幾個(gè)函數(shù)實(shí)例畫一個(gè)Buffer:
Buffer.from()
Buffer.alloc()
Buffer.allocUnsafe()
函數(shù) | 參數(shù) | 返回值 |
---|---|---|
from | arry | 包含array的字節(jié)副本的Buffer,數(shù)組中的每一項(xiàng)表示一個(gè)8位字節(jié)的數(shù)字,故值在0--255以內(nèi),否則取余 |
from | buffer | 從buffer復(fù)制一個(gè)新的buffer |
from | arrayBuffer[,byteOffet,[,length]] | 與arrayBuffer共享內(nèi)存的Buffer |
from | string[,encoding] | string初始化的Buffer |
alloc | size[,fill[encoding]] | 指定大小的Buffer實(shí)例額,省略 fill,默認(rèn)用0填充 |
allocUnsafe | size | 指定大小的buffer,不被初始化,可能包含敏感信息 |
給allocUnsafe分配的內(nèi)存不被初始化,即歸零,內(nèi)存速度快,但是可能包含舊數(shù)據(jù),不覆蓋這些數(shù)據(jù),就可能造成內(nèi)存泄漏。
編碼支持以下編碼:
utf
ascii
base64
binary
utf16le
hex
讀寫緩沖區(qū)buffer.write(string[offset,[length]][,encoding])
string - 寫入緩沖區(qū)的字符串;
offset - 開始寫入的位置,默認(rèn) 0;
length - 寫入字節(jié),默認(rèn) buf.length
encoding - 編碼,默認(rèn) utf8。
返回值:int:寫入的實(shí)際大小,沒有足夠的空間保存,只會(huì)寫入一部分。
buffer.toString([endcoding[,start=0[,end=buffer.length]]]) 解碼指定緩沖區(qū)的數(shù)據(jù),并按 endcoding 編碼格式返回字符串。
let buf = Buffer.alloc(10);//分配 10 個(gè)字節(jié)的空間 console.log(buf)//填充 buffer.fill(value[,offset=0[,end=buffer.length]][,endcoding])沒 fill ,用 0 填充 let len = buf.write("this is a buffer");// 16個(gè)字節(jié) console.log(buf)// console.log(len)//10 // 上面的代碼和下面的一樣 let buffer = Buffer.from("this is a buffer".substring(0, 10)) console.log(buffer)// console.log(buffer.length)//10 let buf2 = Buffer.alloc(8,10);// 分配 8 個(gè)字節(jié)的內(nèi)存,用 10 填充 console.log(buf2)// let size = buf2.write("this a buffer", 2, 2);//從索引 2 開始寫,寫入2字節(jié)的數(shù)據(jù) console.log(buf2)// console.log(size)//2 console.log(buf.toString("utf16le",2,8));//獩槧? console.log(buf.toString("base64",2,8));//aXMgaXMg console.log(buf.toString("ascii",2,8));//is is console.log(buf.toString("utf8",2,8));//is is console.log(buf.toString("hex",2,8));//697320697320
value 可以是 Buffer 、String 、Int。
const buf1 = Buffer.alloc(10).fill("abcd")//空間足夠,循環(huán)填充 console.log(buf1.toString())//abcdabcdab 循環(huán)填充,知道空間滿 const buf2 = Buffer.alloc(3).fill("abcdef");//空間不夠,截?cái)?console.log(buf2.toString());//abc const buf3 = Buffer.alloc(10).fill("abc", 3);//從索引 3 開始填充 console.log(buf3);//console.log(buf3.toString());//abcabcabca const buf4 = Buffer.alloc(10).fill("abc", 3, 7);//從索引 3 開始填充,到索引 7 結(jié)束 console.log(buf4);// console.log(buf4.toString());// abca
let buffer = Buffer.alloc(10).fill("abcd") console.log(buffer.toString()) buffer=Buffer.alloc(10).fill(34) // 改變?cè)瓉淼?buffer console.log(buffer.toString())buffer 比較 buffer.equals(buffer)
比較兩個(gè) buffer 的數(shù)據(jù)是否相同。
// 例子一:編碼一樣,內(nèi)容相同 var buf1 = Buffer.from("A"); var buf2 = Buffer.from("A"); console.log( buf1.equals(buf2) ); // true // 例子二:編碼一樣,內(nèi)容不同 var buf3 = Buffer.from("A"); var buf4 = Buffer.from("B"); console.log( buf3.equals(buf4) ); // false // 例子三:編碼不一樣,內(nèi)容相同 var buf5 = Buffer.from("ABC"); //buf.compare(target[, targetStart[, targetEnd[, sourceStart[, sourceEnd]]]])var buf6 = Buffer.from("414243", "hex");// var buf7 = Buffer.from("414243", "utf16le");// console.log(buf5.equals(buf6));//true console.log(buf7.equals(buf6));//false
compare 可規(guī)定比較的范圍,返回一個(gè)數(shù)字。
const buf1 = Buffer.from("ABC"); const buf2 = Buffer.from("BCD"); const buf3 = Buffer.from("ABCD"); console.log(buf1.compare(buf1));//0 console.log(buf1.compare(buf2));//-1 console.log(buf1.compare(buf3));//-1 console.log(buf2.compare(buf1));//1 console.log(buf2.compare(buf3));//1 // ABC BCD ABCD console.log([buf1, buf2,buf3 ].sort(Buffer.compare));//[arr.sort(Buffer.compare) -- buffer 數(shù)組排序,按位比較,第一位能比出結(jié)果的,就確定了。, , ] ABC ABCD BCD
const buf1 = Buffer.from("81234"); const buf2 = Buffer.from("80234"); const arr = [buf1, buf2]; console.log(arr);//[檢查 buffer, ] console.log(arr.sort(Buffer.compare));//[ , ] 第一位,38=38,不能得出順序,第二位,30 < 31,buf2 排在前面來。
Buffer.isBuffer(object)
計(jì)算需要分配的內(nèi)存Buffer.byteLength(string, encoding=‘utf8’)
buffer 大小 buffer.lengthconsole.log(Buffer.byteLength("??"))// 6 需要 6 個(gè)字節(jié)存儲(chǔ) 兩個(gè)?? let buffer = Buffer.alloc(10).fill("?",4)// 從索引 4 開始存,剛好能存 2 個(gè) ? console.log(buffer.length)// 10 給 buffer 分配的內(nèi)存空間 console.log("??".length)//2 字符串長(zhǎng)度 console.log(buffer.toString())// "??" console.log(buffer.toString().length)// 6 單位是字節(jié) console.log(Buffer.byteLength("??"))// 6 需要 6 個(gè)字節(jié)存儲(chǔ)兩個(gè)? let buffer2 = Buffer.alloc(10).fill("?",5)// 從索引 5 開始存,剛好能存 2 個(gè) ? 還差 1 字節(jié)空間 console.log(buffer2.toString())// "??" 有一個(gè)亂碼 console.log(buffer2.toString().length)// 7buffer 連接 Buffer.concat(bufferList[,totalLength])
totalLength 是所有bufferList 元素長(zhǎng)度的累加。
totalLength > 實(shí)際累加長(zhǎng)度,用 0 填充;
totalLength < 實(shí)際累計(jì)長(zhǎng)度,后面的舍棄。
//接著上面的代碼 let buf3=Buffer.concat(arr,4); console.log(buf3);//復(fù)制 bufSource.copy(bufTarget[,targetStart[,ssourceStart[,sourceEnd]]])舍棄四位 let buf4=Buffer.concat(arr,12); console.log(buf4);// 0 填充兩位
復(fù)制 bufSource 的 sourceStart -- sourceEnd-1 的字節(jié)到 bufTarget 的 target 位置開始存放。
返回值int:實(shí)際存入的字節(jié)數(shù)。目標(biāo) buffer 空間不夠,復(fù)制源會(huì)被階段。
const buf1 = Buffer.alloc(10);//分配 10 個(gè)字節(jié)的空間 const buf2 = Buffer.from("copyFunction"); console.log("復(fù)制前 buf1", buf1);//復(fù)制前 buf1截取 buf.slice([start=0[, end=buf.length]])console.log("復(fù)制前 buf2", buf2);//復(fù)制前 buf2 let result = buf2.copy(buf1, 4, 1, 5);//復(fù)制 buf1 1--5 字節(jié)到 buf2 的 第 4 個(gè)索引位置開始存放,用 6 個(gè)字節(jié)來存放4個(gè)字節(jié)的數(shù)據(jù),空間足夠。 console.log("復(fù)制后 buf1", buf1);//復(fù)制后 buf1 console.log(buf1.toString());//opyF console.log("復(fù)制后 buf2", buf2);//復(fù)制后 buf2 console.log(buf2.toString());//copyFunction console.log("復(fù)制后 result", result);// 4
從 buf 中截取一部分,組成新的 buffer , 兩者內(nèi)存是共享的,所以修改時(shí),會(huì)相互影響。
let buf1 = Buffer.alloc(5).fill("abcd") let buf2 = buf1.slice() console.log(buf2.toString())//abcda let buf3 = buf1.slice(2,4) console.log(buf3)//cd console.log(buf3.toString())//cd // 測(cè)試共享內(nèi)存 console.log(buf3[0]="100")// 100 修改 buf3 的第一個(gè)值 為 d,返回修改后的值 console.log(buf3[0].toString())//100 console.log(buf3)//查找 buf.indexOf(value,byteOffset=0)console.log(buf3.toString())//dd 修改了 console.log(buf1)// console.log(buf1.toString())//abdd buf1 也修改了
從 buf 的 byteOffset 位置開始查找 value,找到一個(gè) value,返回其索引,否則返回 -1。value 可以是 String 、Int 、Buffer。
const buf2 = Buffer.from("copyFunction"); let result = buf2.indexOf("c", 3, "utf8"); let result2 = buf2.indexOf("c"); let result3 = buf2.indexOf("C"); console.log(result);// 7 索引 3 之后第一個(gè) c 的索引 console.log(result2);// 0 第一個(gè) c console.log(result3);// -1 buf2.indexOf(Buffer.from("copy"),2,"utf8");//-1 buf2.indexOf(9,4);//-1
let buffer = Buffer.alloc(10).fill("abcd"); console.log(buffer.toString());// abcdabcdab // 遞歸查找所有buffer let indexs = [];//這里很關(guān)鍵 存儲(chǔ)查找到的下標(biāo) function recursiveIndexOf(buffer, char, start) { if (start < 0) { start = 0; } if (start > buffer.length - 1) { return -1; }// 開始下標(biāo)大于 buffer 最大下標(biāo),返回 -1,也是遞歸出口 let index = buffer.indexOf(char, start); if (index !== -1) { indexs.push(index); recursiveIndexOf(buffer, char, index + 1); } return indexs; } let result = recuisiveIndexOf(buffer, "a", 0); console.log(result);//[0,4,8]buffer 轉(zhuǎn) String 和 Object
buf.toString([encoding=utf8[,start=0[,end=buf.length]]])、buf.toJSON()
toJSON 返回一個(gè)對(duì)象。{type:"Buffer",data:[]} data 是 buffer 的值。
let buffer = Buffer.alloc(10).fill("abcd"); console.log(buffer.toString())//abcd console.log(buffer.toJSON())//{ type: "Buffer",data: [ 97, 98, 99, 100, 97, 98, 99, 100, 97, 98 ] } console.log(Object.getPrototypeOf(buffer.toJSON()))// {} 可見 toJSON 返回的是對(duì)象 console.log(buffer[0])//97 console.log(buffer.toJSON().data[0])//97 console.log(buffer.toJSON().data)//[ 97, 98, 99, 100, 97, 98, 99, 100, 97, 98 ] console.log(JSON.stringify(buffer.toJSON()))// 變成 json 字符串buffer 遍歷
buffer.keys()、buffer.values() 、buffer.entries()
let buffer = Buffer.alloc(10).fill("abcd"); for (let key of buffer.keys()) { process.stdout.write(`${key}`)//輸出不換行,write 只能接收 String 和 Buffer 作為參數(shù),可用模板字符串轉(zhuǎn)換 // console.log(key) 這樣輸出會(huì)換行 } //0123456789 console.log() for (let value of buffer.values()) { process.stdout.write(`${value}`);//9798991009798991009798 } console.log("") for (let entriy of buffer.entries()) { console.log("buffer[%d]==%d", entriy[0], entriy[1]) } /* buffer[0]==97 buffer[1]==98 buffer[2]==99 buffer[3]==100 buffer[4]==97 buffer[5]==98 buffer[6]==99 buffer[7]==100 buffer[8]==97 buffer[9]==98 */TODO
TypeArray vs Buffer vs ArrayBuffer
最后第一次在 SG 寫用 markdown 寫文章,體驗(yàn)并不怎么好,必須字體很小,看的眼疼,代碼顯示不太友好,比如會(huì)出現(xiàn)滾動(dòng)條,不帶行號(hào)等。SG 大佬眾多,歡迎指教。
參考文章:NodeJS stream 一:Buffer
Nodejs進(jìn)階:核心模塊Buffer常用API使用總結(jié)
Do you want a better understanding of Buffer in Node.js? Check this out.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97945.html
摘要:文檔是的核心概念,是鍵值對(duì)的一個(gè)有序集,在里文檔被表示成對(duì)象。創(chuàng)建集合數(shù)據(jù)庫中的集合名稱當(dāng)我們對(duì)其添加數(shù)據(jù)時(shí)如果已經(jīng)存在,則會(huì)保存到其目錄下,如果未存在,則會(huì)創(chuàng)建集合,然后在保存數(shù)據(jù)。使用創(chuàng)建,如下示例連接成功許巍男保存成功保存失敗參考 mongoose簡(jiǎn)介 mongoose網(wǎng)站:https://mongoosejs.com/ 為什么要用Mongoose Mongoose就是一個(gè)讓我們...
摘要:與字符編碼通過指定的編碼進(jìn)制,可以在與普通的字符串之間轉(zhuǎn)換。中文中文通常用于實(shí)例數(shù)組的排序。有點(diǎn)像方法合并截?cái)酁榈拈L(zhǎng)度,缺少的部分會(huì)用補(bǔ)充,是一個(gè)返回,是一個(gè)支持的字符編碼返回,創(chuàng)建并返回一個(gè)形式的迭代器,如果與具有完全相同的字節(jié)就返回 Buffer 可以在TCP流或者文件系統(tǒng)操作等場(chǎng)景中處理二進(jìn)制數(shù)據(jù)流。 Buffer實(shí)例類似于整數(shù)數(shù)組,但是Buffer大小固定、且在V8堆外分配物理...
摘要:回調(diào)函數(shù)將接收到一個(gè)對(duì)象。要禁止這一默認(rèn)行為,選項(xiàng)應(yīng)該指定為。一般來說,建議開發(fā)人員避免使用事件和方法,使用或事件代替。事件在寫入數(shù)據(jù)出錯(cuò)或者使用管道出錯(cuò)時(shí)觸發(fā),事件發(fā)生時(shí),回調(diào)函數(shù)僅會(huì)接收到一個(gè)參數(shù)。注意事件發(fā)生時(shí),流并不會(huì)關(guān)閉。 Stream 流可以是可讀的、可寫的、或者是可讀寫的。所有的流都是EventEmitter的實(shí)例。 對(duì)象模式 所有使用Node.js API創(chuàng)建的流對(duì)象都...
摘要:不能用于機(jī)器學(xué)習(xí)太慢幻覺矩陣操作太難有函數(shù)庫啊,比如只能用于前端開發(fā)開發(fā)者笑了機(jī)器學(xué)習(xí)庫都是開發(fā)者機(jī)器學(xué)習(xí)庫神經(jīng)網(wǎng)絡(luò)神經(jīng)網(wǎng)絡(luò)自然語言處理卷積神經(jīng)網(wǎng)絡(luò)一系列庫神經(jīng)網(wǎng)絡(luò)深度學(xué)習(xí)我們將使用來實(shí)現(xiàn)線性回歸,源代碼在倉庫。 譯者按: AI時(shí)代,不會(huì)機(jī)器學(xué)習(xí)的JavaScript開發(fā)者不是好的前端工程師。 原文: Machine Learning with JavaScript : Part 1 ...
閱讀 3579·2023-04-26 02:05
閱讀 2024·2021-11-19 11:30
閱讀 4236·2021-09-30 09:59
閱讀 3190·2021-09-10 10:51
閱讀 2615·2021-09-01 10:30
閱讀 1501·2021-08-11 11:20
閱讀 2629·2019-08-30 15:54
閱讀 575·2019-08-30 10:49