摘要:核心模塊學習之何為在引入之前,沒有能讀取和操作二進制數據流的機制,作為引入,以便能和網絡流文件流等進行交互。返回值寫入的實際大小,沒有足夠的空間保存,只會寫入一部分。返回值實際存入的字節數。參考文章一進階核心模塊常用使用總結
node 核心模塊學習之Buffer 何為 Buffer
在ES6引入 TypeArray 之前,JS沒有能讀取和操作二進制數據流的機制,Buffer 作為 Node API 引入,以便能和 TCP 網絡流、文件流等進行交互。 目前 ES6 中有 TypeArray 了,Buffer 類以更加優化和適用的于 Node 操作的方式實現了 Unit8Array API。
總之,Buffer 就是用來操作二進制數據的,位于全局變量中,無需引入即可使用。
Buffer 實例類似于 整型數組,緩沖區大小在創建是確定,不能調整,內存有C++申請,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 緩存區,計算機讀取速度和處理不匹配,讀取速度高于處理速度時,會開辟一段內存區域存放待處理的數據,這個段內存就叫緩沖區。
實例化 Buffer在v6.0之前創建Buffer對象直接使用new Buffer()構造函數來創建對象實例,但是Buffer對內存的權限操作相比很大,可以直接捕獲一些敏感信息,存在安全隱患,之后的版本,用下面幾個函數實例畫一個Buffer:
Buffer.from()
Buffer.alloc()
Buffer.allocUnsafe()
函數 | 參數 | 返回值 |
---|---|---|
from | arry | 包含array的字節副本的Buffer,數組中的每一項表示一個8位字節的數字,故值在0--255以內,否則取余 |
from | buffer | 從buffer復制一個新的buffer |
from | arrayBuffer[,byteOffet,[,length]] | 與arrayBuffer共享內存的Buffer |
from | string[,encoding] | string初始化的Buffer |
alloc | size[,fill[encoding]] | 指定大小的Buffer實例額,省略 fill,默認用0填充 |
allocUnsafe | size | 指定大小的buffer,不被初始化,可能包含敏感信息 |
給allocUnsafe分配的內存不被初始化,即歸零,內存速度快,但是可能包含舊數據,不覆蓋這些數據,就可能造成內存泄漏。
編碼支持以下編碼:
utf
ascii
base64
binary
utf16le
hex
讀寫緩沖區buffer.write(string[offset,[length]][,encoding])
string - 寫入緩沖區的字符串;
offset - 開始寫入的位置,默認 0;
length - 寫入字節,默認 buf.length
encoding - 編碼,默認 utf8。
返回值:int:寫入的實際大小,沒有足夠的空間保存,只會寫入一部分。
buffer.toString([endcoding[,start=0[,end=buffer.length]]]) 解碼指定緩沖區的數據,并按 endcoding 編碼格式返回字符串。
let buf = Buffer.alloc(10);//分配 10 個字節的空間 console.log(buf)//填充 buffer.fill(value[,offset=0[,end=buffer.length]][,endcoding])沒 fill ,用 0 填充 let len = buf.write("this is a buffer");// 16個字節 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 個字節的內存,用 10 填充 console.log(buf2)// let size = buf2.write("this a buffer", 2, 2);//從索引 2 開始寫,寫入2字節的數據 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")//空間足夠,循環填充 console.log(buf1.toString())//abcdabcdab 循環填充,知道空間滿 const buf2 = Buffer.alloc(3).fill("abcdef");//空間不夠,截斷 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 結束 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) // 改變原來的 buffer console.log(buffer.toString())buffer 比較 buffer.equals(buffer)
比較兩個 buffer 的數據是否相同。
// 例子一:編碼一樣,內容相同 var buf1 = Buffer.from("A"); var buf2 = Buffer.from("A"); console.log( buf1.equals(buf2) ); // true // 例子二:編碼一樣,內容不同 var buf3 = Buffer.from("A"); var buf4 = Buffer.from("B"); console.log( buf3.equals(buf4) ); // false // 例子三:編碼不一樣,內容相同 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 可規定比較的范圍,返回一個數字。
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 數組排序,按位比較,第一位能比出結果的,就確定了。, , ] 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)
計算需要分配的內存Buffer.byteLength(string, encoding=‘utf8’)
buffer 大小 buffer.lengthconsole.log(Buffer.byteLength("??"))// 6 需要 6 個字節存儲 兩個?? let buffer = Buffer.alloc(10).fill("?",4)// 從索引 4 開始存,剛好能存 2 個 ? console.log(buffer.length)// 10 給 buffer 分配的內存空間 console.log("??".length)//2 字符串長度 console.log(buffer.toString())// "??" console.log(buffer.toString().length)// 6 單位是字節 console.log(Buffer.byteLength("??"))// 6 需要 6 個字節存儲兩個? let buffer2 = Buffer.alloc(10).fill("?",5)// 從索引 5 開始存,剛好能存 2 個 ? 還差 1 字節空間 console.log(buffer2.toString())// "??" 有一個亂碼 console.log(buffer2.toString().length)// 7buffer 連接 Buffer.concat(bufferList[,totalLength])
totalLength 是所有bufferList 元素長度的累加。
totalLength > 實際累加長度,用 0 填充;
totalLength < 實際累計長度,后面的舍棄。
//接著上面的代碼 let buf3=Buffer.concat(arr,4); console.log(buf3);//復制 bufSource.copy(bufTarget[,targetStart[,ssourceStart[,sourceEnd]]])舍棄四位 let buf4=Buffer.concat(arr,12); console.log(buf4);// 0 填充兩位
復制 bufSource 的 sourceStart -- sourceEnd-1 的字節到 bufTarget 的 target 位置開始存放。
返回值int:實際存入的字節數。目標 buffer 空間不夠,復制源會被階段。
const buf1 = Buffer.alloc(10);//分配 10 個字節的空間 const buf2 = Buffer.from("copyFunction"); console.log("復制前 buf1", buf1);//復制前 buf1截取 buf.slice([start=0[, end=buf.length]])console.log("復制前 buf2", buf2);//復制前 buf2 let result = buf2.copy(buf1, 4, 1, 5);//復制 buf1 1--5 字節到 buf2 的 第 4 個索引位置開始存放,用 6 個字節來存放4個字節的數據,空間足夠。 console.log("復制后 buf1", buf1);//復制后 buf1 console.log(buf1.toString());//opyF console.log("復制后 buf2", buf2);//復制后 buf2 console.log(buf2.toString());//copyFunction console.log("復制后 result", result);// 4
從 buf 中截取一部分,組成新的 buffer , 兩者內存是共享的,所以修改時,會相互影響。
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 // 測試共享內存 console.log(buf3[0]="100")// 100 修改 buf3 的第一個值 為 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,找到一個 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 之后第一個 c 的索引 console.log(result2);// 0 第一個 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 = [];//這里很關鍵 存儲查找到的下標 function recursiveIndexOf(buffer, char, start) { if (start < 0) { start = 0; } if (start > buffer.length - 1) { return -1; }// 開始下標大于 buffer 最大下標,返回 -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 轉 String 和 Object
buf.toString([encoding=utf8[,start=0[,end=buf.length]]])、buf.toJSON()
toJSON 返回一個對象。{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 返回的是對象 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 作為參數,可用模板字符串轉換 // console.log(key) 這樣輸出會換行 } //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 寫文章,體驗并不怎么好,必須字體很小,看的眼疼,代碼顯示不太友好,比如會出現滾動條,不帶行號等。SG 大佬眾多,歡迎指教。
參考文章:NodeJS stream 一:Buffer
Nodejs進階:核心模塊Buffer常用API使用總結
Do you want a better understanding of Buffer in Node.js? Check this out.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97945.html
摘要:文檔是的核心概念,是鍵值對的一個有序集,在里文檔被表示成對象。創建集合數據庫中的集合名稱當我們對其添加數據時如果已經存在,則會保存到其目錄下,如果未存在,則會創建集合,然后在保存數據。使用創建,如下示例連接成功許巍男保存成功保存失敗參考 mongoose簡介 mongoose網站:https://mongoosejs.com/ 為什么要用Mongoose Mongoose就是一個讓我們...
摘要:與字符編碼通過指定的編碼進制,可以在與普通的字符串之間轉換。中文中文通常用于實例數組的排序。有點像方法合并截斷為的長度,缺少的部分會用補充,是一個返回,是一個支持的字符編碼返回,創建并返回一個形式的迭代器,如果與具有完全相同的字節就返回 Buffer 可以在TCP流或者文件系統操作等場景中處理二進制數據流。 Buffer實例類似于整數數組,但是Buffer大小固定、且在V8堆外分配物理...
摘要:回調函數將接收到一個對象。要禁止這一默認行為,選項應該指定為。一般來說,建議開發人員避免使用事件和方法,使用或事件代替。事件在寫入數據出錯或者使用管道出錯時觸發,事件發生時,回調函數僅會接收到一個參數。注意事件發生時,流并不會關閉。 Stream 流可以是可讀的、可寫的、或者是可讀寫的。所有的流都是EventEmitter的實例。 對象模式 所有使用Node.js API創建的流對象都...
摘要:不能用于機器學習太慢幻覺矩陣操作太難有函數庫啊,比如只能用于前端開發開發者笑了機器學習庫都是開發者機器學習庫神經網絡神經網絡自然語言處理卷積神經網絡一系列庫神經網絡深度學習我們將使用來實現線性回歸,源代碼在倉庫。 譯者按: AI時代,不會機器學習的JavaScript開發者不是好的前端工程師。 原文: Machine Learning with JavaScript : Part 1 ...
閱讀 3564·2023-04-26 02:05
閱讀 2003·2021-11-19 11:30
閱讀 4202·2021-09-30 09:59
閱讀 3175·2021-09-10 10:51
閱讀 2605·2021-09-01 10:30
閱讀 1470·2021-08-11 11:20
閱讀 2615·2019-08-30 15:54
閱讀 563·2019-08-30 10:49