Node.js Buffer對象

2021-09-15 16:32 更新

概述

Buffer對象是Node.js用來處理二進制數(shù)據(jù)的一個接口。JavaScript比較擅長處理Unicode數(shù)據(jù),對于處理二進制格式的數(shù)據(jù)(比如TCP數(shù)據(jù)流),就不太擅長。Buffer對象就是為了解決這個問題而提供的。該對象也是一個構(gòu)造函數(shù),它的實例代表了V8引擎分配的一段內(nèi)存,基本上是一個數(shù)組,成員都為整數(shù)值。

Buffer是Node原生提供的全局對象,可以直接使用,不需要require('buffer')

Buffer對象與字符串的互相轉(zhuǎn)換,需要指定編碼格式。目前,Buffer對象支持以下編碼格式。

  • ascii
  • utf8
  • utf16le:UTF-16的小頭編碼,支持大于U+10000的四字節(jié)字符。
  • ucs2:utf16le的別名。
  • base64
  • hex:將每個字節(jié)轉(zhuǎn)為兩個十六進制字符。

V8引擎將Buffer對象占用的內(nèi)存,解釋為一個整數(shù)數(shù)組,而不是二進制數(shù)組。所以,new Uint32Array(new Buffer([1,2,3,4])),生成的Uint32Array數(shù)組是一個4個成員的Uint32Array數(shù)組,而不是只有單個成員([0x1020304]或者[0x4030201])的。

注意,這時類型化數(shù)組所對應的內(nèi)存是從Buffer對象拷貝的,而不是共享的。類型化數(shù)組的buffer屬性,保留指向原Buffer對象的指針。

類型化數(shù)組的操作,與Buffer對象的操作基本上是兼容的,只有輕微的差異。比如,類型化數(shù)組的slice方法返回原內(nèi)存的拷貝,而Buffer對象的slice方法創(chuàng)造原內(nèi)存的一個視圖(view)。

Buffer構(gòu)造函數(shù)

Buffer作為構(gòu)造函數(shù),可以用new命令生成一個實例,它可以接受多種形式的參數(shù)。

// 參數(shù)是整數(shù),指定分配多少個字節(jié)內(nèi)存
var hello = new Buffer(5);

// 參數(shù)是數(shù)組,數(shù)組成員必須是整數(shù)值
var hello = new Buffer([0x48, 0x65, 0x6c, 0x6c, 0x6f]);
hello.toString() // 'Hello'

// 參數(shù)是字符串(默認為utf8編碼)
var hello = new Buffer('Hello');

// 參數(shù)是字符串(不省略編碼)
var hello = new Buffer('Hello', 'utf8');

// 參數(shù)是另一個Buffer實例,等同于拷貝后者
var hello1 = new Buffer('Hello');
var hello2 = new Buffer(hello1);

類的方法

Buffer.isEncoding()

Buffer.isEncoding方法返回一個布爾值,表示Buffer實例是否為指定編碼。

Buffer.isEncoding('utf8')
// true

Buffer.isBuffer()

Buffer.isBuffer方法接受一個對象作為參數(shù),返回一個布爾值,表示該對象是否為Buffer實例。

Buffer.isBuffer(Date) // false

Buffer.byteLength()

Buffer.byteLength方法返回字符串實際占據(jù)的字節(jié)長度,默認編碼方式為utf8。

Buffer.byteLength('Hello', 'utf8') // 5

Buffer.concat()

Buffer.concat方法將一組Buffer對象合并為一個Buffer對象。

var i1 = new Buffer('Hello');
var i2 = new Buffer(' ');
var i3 = new Buffer('World');
Buffer.concat([i1, i2, i3]).toString()
// 'Hello World'

需要注意的是,如果Buffer.concat的參數(shù)數(shù)組只有一個成員,就直接返回該成員。如果有多個成員,就返回一個多個成員合并的新Buffer對象。

Buffer.concat方法還可以接受第二個參數(shù),指定合并后Buffer對象的總長度。

var i1 = new Buffer('Hello');
var i2 = new Buffer(' ');
var i3 = new Buffer('World');
Buffer.concat([i1, i2, i3], 10).toString()
// 'Hello Worl'

省略第二個參數(shù)時,Node內(nèi)部會計算出這個值,然后再據(jù)此進行合并運算。因此,顯式提供這個參數(shù),能提供運行速度。

實例屬性

length

length屬性返回Buffer對象所占據(jù)的內(nèi)存長度。注意,這個值與Buffer對象的內(nèi)容無關(guān)。

buf = new Buffer(1234);
buf.length // 1234

buf.write("some string", 0, "ascii");
buf.length // 1234

上面代碼中,不管寫入什么內(nèi)容,length屬性總是返回Buffer對象的空間長度。如果想知道一個字符串所占據(jù)的字節(jié)長度,可以將其傳入Buffer.byteLength方法。

length屬性是可寫的,但是這會導致未定義的行為,不建議使用。如果想修改Buffer對象的長度,建議使用slice方法返回一個新的Buffer對象。

實例方法

write()

write方法可以向指定的Buffer對象寫入數(shù)據(jù)。它的第一個參數(shù)是所寫入的內(nèi)容,第二個參數(shù)(可省略)是所寫入的起始位置(從0開始),第三個參數(shù)(可省略)是編碼方式,默認為utf8。

var buf = new Buffer(5);
buf.write('He');
buf.write('l', 2);
buf.write('lo', 3);
console.log(buf.toString());
// "Hello"

slice()

slice方法返回一個按照指定位置、從原對象切割出來的Buffer實例。它的兩個參數(shù)分別為切割的起始位置和終止位置。

var buf = new Buffer('just some data');
var chunk = buf.slice(4, 9);
chunk.toString()
// "some"

toString()

toString方法將Buffer對象,按照指定編碼(默認為utf8)轉(zhuǎn)為字符串。

var hello = new Buffer('Hello');
hello // <Buffer 48 65 6c 6c 6f>
hello.toString() // "Hello"

toString方法可以只返回指定位置內(nèi)存的內(nèi)容,它的第二個參數(shù)表示起始位置,第三個參數(shù)表示終止位置,兩者都是從0開始計算。

var buf = new Buffer('just some data');
console.log(buf.toString('ascii', 4, 9));
// "some"

toJSON()

toJSON方法將Buffer實例轉(zhuǎn)為JSON對象。如果JSON.stringify方法調(diào)用Buffer實例,默認會先調(diào)用toJSON方法。

var buf = new Buffer('test');
var json = JSON.stringify(buf);
json // '[116,101,115,116]'

var copy = new Buffer(JSON.parse(json));
copy // <Buffer 74 65 73 74>
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號