您好,登錄后才能下訂單哦!
這篇文章給大家介紹Nodejs中有哪些Buffer模塊的API,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
Buffer是node的核心模塊,開發(fā)者可以利用它來處理二進(jìn)制數(shù)據(jù),比如文件流的讀寫、網(wǎng)絡(luò)請求數(shù)據(jù)的處理等。
Buffer的API非常多,本文僅挑選 比較常用/容易理解 的API進(jìn)行講解,包括Buffer實(shí)例的創(chuàng)建、比較、連接、拷貝、查找、遍歷、類型轉(zhuǎn)換、截取、編碼轉(zhuǎn)換等?!就扑]學(xué)習(xí):《nodejs 教程》】
new Buffer(array)
Buffer.alloc(length)
Buffer.allocUnsafe(length)
Buffer.from(array)
// Creates a new Buffer containing the ASCII bytes of the string 'buffer' const buf = new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
驗(yàn)證下:
var array = 'buffer'.split('').map(function(v){ return '0x' + v.charCodeAt(0).toString(16) }); console.log( array.join() ); // 輸出:0x62,0x75,0x66,0x66,0x65,0x72
var buf1 = Buffer.alloc(10); // 長度為10的buffer,初始值為0x0 var buf2 = Buffer.alloc(10, 1); // 長度為10的buffer,初始值為0x1
var buf3 = Buffer.allocUnsafe(10); // 長度為10的buffer,初始值不確定
var buf4 = Buffer.from([1, 2, 3]) // 長度為3的buffer,初始值為 0x01, 0x02, 0x03
例子一:Buffer.from(array)
// [0x62, 0x75, 0x66, 0x66, 0x65, 0x72] 為字符串 "buffer" // 0x62 為16進(jìn)制,轉(zhuǎn)成十進(jìn)制就是 98,代表的就是字母 b var buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); console.log(buf.toString());
例子二:Buffer.from(string[, encoding])
通過string創(chuàng)建buffer,跟將buffer轉(zhuǎn)成字符串時(shí),記得編碼保持一致,不然會(huì)出現(xiàn)亂碼,如下所示。
var buf = Buffer.from('this is a tést'); // 默認(rèn)采用utf8 // 輸出:this is a tést console.log(buf.toString()); // 默認(rèn)編碼是utf8,所以正常打印 // 輸出:this is a tC)st console.log(buf.toString('ascii')); // 轉(zhuǎn)成字符串時(shí),編碼不是utf8,所以亂碼
對亂碼的分析如下:
var letter = 'é'; var buff = Buffer.from(letter); // 默認(rèn)編碼是utf8,這里占據(jù)兩個(gè)字節(jié) <Buffer c3 a9> var len = buff.length; // 2 var code = buff[0]; // 第一個(gè)字節(jié)為0xc3,即195:超出ascii的最大支持范圍 var binary = code.toString(2); // 195的二進(jìn)制:10101001 var finalBinary = binary.slice(1); // 將高位的1舍棄,變成:0101001 var finalCode = parseInt(finalBinary, 2); // 0101001 對應(yīng)的十進(jìn)制:67 var finalLetter = String.fromCharCode(finalCode); // 67對應(yīng)的字符:C // 同理 0xa9最終轉(zhuǎn)成的ascii字符為) // 所以,最終輸出為 this is a tC)st
例子三:Buffer.from(buffer)
創(chuàng)建新的Buffer實(shí)例,并將buffer的數(shù)據(jù)拷貝到新的實(shí)例子中去。
var buff = Buffer.from('buffer'); var buff2 = Buffer.from(buff); console.log(buff.toString()); // 輸出:buffer console.log(buff2.toString()); // 輸出:buffer buff2[0] = 0x61; console.log(buff.toString()); // 輸出:buffer console.log(buff2.toString()); // 輸出:auffer
判斷兩個(gè)buffer實(shí)例存儲(chǔ)的數(shù)據(jù)是否相同,如果是,返回true,否則返回false。
// 例子一:編碼一樣,內(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'); // <Buffer 41 42 43> var buf6 = Buffer.from('414243', 'hex'); console.log(buf5.equals(buf6)); //true //只要比較的兩者內(nèi)容相同,`buf.equals(otherBuffer)` 就返回true
同樣是對兩個(gè)buffer實(shí)例進(jìn)行比較,不同的是:
可以指定特定比較的范圍(通過start、end指定)
返回值為整數(shù),達(dá)標(biāo)buf、target的大小關(guān)系
假設(shè)返回值為
0
:buf、target大小相同。
1
:buf大于target,也就是說buf應(yīng)該排在target之后。
-1
:buf小于target,也就是說buf應(yīng)該排在target之前。
看例子,官方的例子挺好的,直接貼一下:
const buf1 = Buffer.from('ABC'); const buf2 = Buffer.from('BCD'); const buf3 = Buffer.from('ABCD'); // Prints: 0 console.log(buf1.compare(buf1)); // Prints: -1 console.log(buf1.compare(buf2)); // Prints: -1 console.log(buf1.compare(buf3)); // Prints: 1 console.log(buf2.compare(buf1)); // Prints: 1 console.log(buf2.compare(buf3)); // Prints: [ <Buffer 41 42 43>, <Buffer 41 42 43 44>, <Buffer 42 43 44> ] // (This result is equal to: [buf1, buf3, buf2]) console.log([buf1, buf2, buf3].sort(Buffer.compare));
跟 buf.compare(target)
大同小異,一般用于排序。直接貼官方例子:
const buf1 = Buffer.from('1234'); const buf2 = Buffer.from('0123'); const arr = [buf1, buf2]; // Prints: [ <Buffer 30 31 32 33>, <Buffer 31 32 33 34> ] // (This result is equal to: [buf2, buf1]) console.log(arr.sort(Buffer.compare));
這里稍微研究下Buffer.from(array)。下面是官方文檔對API的說明,也就是說,每個(gè)array的元素對應(yīng)1個(gè)字節(jié)(8位),取值從0到255。
Allocates a new Buffer using an array of octets.
首先看下,傳入的元素為數(shù)字的場景。下面分別是10進(jìn)制、8進(jìn)制、16進(jìn)制,跟預(yù)期中的結(jié)果一致。
var buff = Buffer.from([62]) // <Buffer 3e> // buff[0] === parseInt('3e', 16) === 62
var buff = Buffer.from([062]) // <Buffer 32> // buff[0] === parseInt(62, 8) === parseInt(32, 16) === 50
var buff = Buffer.from([0x62]) // <Buffer 62> // buff[0] === parseInt(62, 16) === 98
再看下,傳入的元素為字符串的場景。
0
開頭的字符串,在parseInt('062')時(shí),可以解釋為62,也可以解釋為50(八進(jìn)制),這里看到采用了第一種解釋。
字符串的場景,跟parseInt()有沒有關(guān)系,暫未深入探究,只是這樣猜想。TODO(找時(shí)間研究下)
var buff = Buffer.from(['62']) // <Buffer 3e> // buff[0] === parseInt('3e', 16) === parseInt('62') === 62
var buff = Buffer.from(['062']) // <Buffer 3e> // buff[0] === parseInt('3e', 16) === parseInt('062') === 62
var buff = Buffer.from(['0x62']) // <Buffer 62> // buff[0] === parseInt('62', 16) === parseInt('0x62') === 98
感興趣的同學(xué)自行探究。
var buff = Buffer.from([256]) // <Buffer 00>
一開始不自覺的會(huì)將Buffer.from('1')[0]
跟"1"
劃等號(hào),其實(shí)"1"
對應(yīng)的編碼是49。
var buff = Buffer.from('1') // <Buffer 31> console.log(buff[0] === 1) // false
這樣對比就知道了,編碼為1的是個(gè)控制字符,表示 Start of Heading。
console.log( String.fromCharCode(49) ) // '1' console.log( String.fromCharCode(1) ) // '\u0001'
備注:個(gè)人覺得totalLength
這個(gè)參數(shù)挺多余的,從官方文檔來看,是處于性能提升的角度考慮。不過內(nèi)部實(shí)現(xiàn)也只是遍歷list,將length累加得到totalLength,從這點(diǎn)來看,性能優(yōu)化是幾乎可以忽略不計(jì)的。
var buff1 = Buffer.alloc(10); var buff2 = Buffer.alloc(20); var totalLength = buff1.length + buff2.length; console.log(totalLength); // 30 var buff3 = Buffer.concat([buff1, buff2], totalLength); console.log(buff3.length); // 30
除了上面提到的性能優(yōu)化,totalLength還有兩點(diǎn)需要注意。假設(shè)list里面所有buffer的長度累加和為length
totalLength > length:返回長度為totalLength的Buffer實(shí)例,超出長度的部分填充0。
totalLength < length:返回長度為totalLength的Buffer實(shí)例,后面部分舍棄。
var buff4 = Buffer.from([1, 2]); var buff5 = Buffer.from([3, 4]); var buff6 = Buffer.concat([buff4, buff5], 5); console.log(buff6.length); // console.log(buff6); // <Buffer 01 02 03 04 00> var buff7 = Buffer.concat([buff4, buff5], 3); console.log(buff7.length); // 3 console.log(buff7); // <Buffer 01 02 03>
使用比較簡單,如果忽略后面三個(gè)參數(shù),那就是將buf的數(shù)據(jù)拷貝到target里去,如下所示:
var buff1 = Buffer.from([1, 2]); var buff2 = Buffer.alloc(2); buff1.copy(buff2); console.log(buff2); // <Buffer 01 02>
另外三個(gè)參數(shù)比較直觀,直接看官方例子
const buf1 = Buffer.allocUnsafe(26); const buf2 = Buffer.allocUnsafe(26).fill('!'); for (let i = 0 ; i < 26 ; i++) { // 97 is the decimal ASCII value for 'a' buf1[i] = i + 97; } buf1.copy(buf2, 8, 16, 20); // Prints: !!!!!!!!qrst!!!!!!!!!!!!! console.log(buf2.toString('ascii', 0, 25));
跟數(shù)組的查找差不多,需要注意的是,value可能是String、Buffer、Integer中的任意類型。
String:如果是字符串,那么encoding就是其對應(yīng)的編碼,默認(rèn)是utf8。
Buffer:如果是Buffer實(shí)例,那么會(huì)將value中的完整數(shù)據(jù),跟buf進(jìn)行對比。
Integer:如果是數(shù)字,那么value會(huì)被當(dāng)做無符號(hào)的8位整數(shù),取值范圍是0到255。
另外,可以通過byteOffset
來指定起始查找位置。
直接上代碼,官方例子妥妥的,耐心看完它基本就理解得差不多了。
const buf = Buffer.from('this is a buffer'); // Prints: 0 console.log(buf.indexOf('this')); // Prints: 2 console.log(buf.indexOf('is')); // Prints: 8 console.log(buf.indexOf(Buffer.from('a buffer'))); // Prints: 8 // (97 is the decimal ASCII value for 'a') console.log(buf.indexOf(97)); // Prints: -1 console.log(buf.indexOf(Buffer.from('a buffer example'))); // Prints: 8 console.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8))); const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); // Prints: 4 console.log(utf16Buffer.indexOf('\u03a3', 0, 'ucs2')); // Prints: 6 console.log(utf16Buffer.indexOf('\u03a3', -4, 'ucs2'));
將sring寫入buf實(shí)例,同時(shí)返回寫入的字節(jié)數(shù)。
參數(shù)如下:
string:寫入的字符串。
offset:從buf的第幾位開始寫入,默認(rèn)是0。
length:寫入多少個(gè)字節(jié),默認(rèn)是 buf.length - offset。
encoding:字符串的編碼,默認(rèn)是utf8。
看個(gè)簡單例子
var buff = Buffer.alloc(4); buff.write('a'); // 返回 1 console.log(buff); // 打印 <Buffer 61 00 00 00> buff.write('ab'); // 返回 2 console.log(buff); // 打印 <Buffer 61 62 00 00>
用value
填充buf,常用于初始化buf。參數(shù)說明如下:
value:用來填充的內(nèi)容,可以是Buffer、String或Integer。
offset:從第幾位開始填充,默認(rèn)是0。
end:停止填充的位置,默認(rèn)是 buf.length。
encoding:如果value
是String,那么為value
的編碼,默認(rèn)是utf8。
例子:
var buff = Buffer.alloc(20).fill('a'); console.log(buff.toString()); // aaaaaaaaaaaaaaaaaaaa
把buf解碼成字符串,用法比較直觀,看例子
var buff = Buffer.from('hello'); console.log( buff.toString() ); // hello console.log( buff.toString('utf8', 0, 2) ); // he
var buff = Buffer.from('hello'); console.log( buff.toJSON() ); // { type: 'Buffer', data: [ 104, 101, 108, 108, 111 ] }
用于對buf
進(jìn)行for...of
遍歷,直接看例子。
var buff = Buffer.from('abcde'); for(const key of buff.keys()){ console.log('key is %d', key); } // key is 0 // key is 1 // key is 2 // key is 3 // key is 4 for(const value of buff.values()){ console.log('value is %d', value); } // value is 97 // value is 98 // value is 99 // value is 100 // value is 101 for(const pair of buff.entries()){ console.log('buff[%d] === %d', pair[0], pair[1]); } // buff[0] === 97 // buff[1] === 98 // buff[2] === 99 // buff[3] === 100 // buff[4] === 101
用于截取buf,并返回一個(gè)新的Buffer實(shí)例。需要注意的是,這里返回的Buffer實(shí)例,指向的仍然是buf的內(nèi)存地址,所以對新Buffer實(shí)例的修改,也會(huì)影響到buf。
var buff1 = Buffer.from('abcde'); console.log(buff1); // <Buffer 61 62 63 64 65> var buff2 = buff1.slice(); console.log(buff2); // <Buffer 61 62 63 64 65> var buff3 = buff1.slice(1, 3); console.log(buff3); // <Buffer 62 63> buff3[0] = 97; // parseInt(61, 16) ==> 97 console.log(buff1); // <Buffer 62 63>
創(chuàng)建、拷貝、截取、轉(zhuǎn)換、查找
buffer、arraybuffer、dataview、typedarray
buffer vs 編碼
Buffer.from()、Buffer.alloc()、Buffer.alocUnsafe()
Buffer vs TypedArray
關(guān)于Nodejs中有哪些Buffer模塊的API就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。