nodejs系列(4)Buffer(緩沖器)


JavaScript的數據類型有字符串、數字、布爾、數組、對象、Null、Undefined,但是卻沒有處理二進制的數據類型。然而在處理像TCP流或文件流時,必須使用到二進制數據。因此在 Node.js中,定義了一個 Buffer 類,該類用來創建一個專門存放二進制數據的緩存區。每當需要在 Node.js 中處理I/O操作中移動的數據時,就有可能使用 Buffer 庫。一個 Buffer 類似於一個整數數組,但它對應於 V8 堆內存之外的一塊原始內存。

(注)Buffer 類在 Node.js 中是一個全局變量,因此調用時無需使用 require('buffer').Buffer。


什么是Buffer?


舉個例子,以字符串為例,字符串與Buffer的應用關系如下:

數據A(字符串+該字符串的編碼) => Buffer對象 => 網絡傳輸或讀寫 => 解碼Buffer => 數據A

(注)編碼解碼默認的都是UTF-8,所以在實際中無需特意修改編碼和解碼格式,除非有特殊需求。

按照上面的規則,我們創建一個Buffer對象如下:

var buf = Buffer.from('你好', 'utf-8');
console.log(buf.toString('utf-8')); //你好
數據A就是'你好+utf-8',buf就是Buffer對象,buf.toString('utf-8')就是按格式解碼為字符串,最后打印出'你好'。由於默認編碼和解碼都是utf-8,上例中可以寫成:

var buf = Buffer.from('你好');
console.log(buf.toString()); //你好
如果我們換種編碼會怎么樣?比如說用hex,將每個字節編碼為兩個十六進制字符。

var buf = Buffer.from('e4bda0e5a5bd', 'hex');
console.log(buf.toString('hex')); //e4bda0e5a5bd
console.log(buf.toString()); //你好
hex編碼的e4bda0e5a5bd字符串實際上就是utf-8編碼的'你好',更形象的說就是漢語'你好'等於英語的'Hello'一樣,不同的編碼可以理解成不同國家的語言,buf就是全世界都通用的世界語,世界語'你好'可以轉為漢語'你好'或者英語的'Hello',而這個世界語就是計算機可以理解的語言。


創建固定長度的Buffer


通過Buffer.from('字符串')創建的Buffer空間長度等於字符串的長度,若需指定空間大小的Buffer,可以通過Buffer.alloc(長度)定義,如

var buf = Buffer.alloc(256);
buf.write("你好", 0, 3);
console.log(buf.toString()); //你
buf.write("你好");
console.log(buf.toString()); //你好
上例中創建了長度為256的Buffer,第一段寫入中,寫入位置為0-3,這個位置只夠寫入一個'你'字,因為一個漢字占3個Buffer長度空間。若沒有設置具體的開始位置和結束位置時,將在0位置開始全部寫入,故第二段中寫入了'你好'。


合並Buffer


在實際應用中,如需實現斷點續載,我們就要將多個Buffer合並組成一個更大的Buffer,合並方法可以使用:Buffer.concat(list[, totalLength])。

var buffer1 = Buffer.from('歡迎大家來到');
var buffer2 = Buffer.from('中國');
var buffer3 = Buffer.concat([buffer1, buffer2], 12); //12為buffer3的空間長度
console.log("合並內容:" + buffer3.toString()); // 合並內容:歡迎大家
console.log("合並長度:" + buffer3.length); // 合並長度:12
var buffer4 = Buffer.concat([buffer1, buffer2]);
console.log("合並內容:" + buffer4.toString()); // 合並內容:歡迎大家來到中國
console.log("合並長度:" + buffer4.length); // 合並長度:24
buffer3有設置了空間長度為12,buffer4為自動設定長度(buffer1+buffer2的長度總和),故buffer3僅顯示是' 歡迎大家',而buffer4則全部顯示了'歡迎大家來到中國'。


比較Buffer


比較兩個Buffer是否相同,使用Buffer.compare(buf1, buf2)。

var buffer1 = Buffer.from('你好');
var buffer2 = Buffer.from('e4bda0e5a5bd', 'hex');
var result = buffer1.compare(buffer2);
if(result == 0) {
console.log(buffer1 + " 與 " + buffer2 + " 相同");
} else {
console.log(buffer1 + " 與 " + buffer2 + " 不同");
}
//打印 : 你好 與 你好 相同
上面utf-8編碼的'你好'與hex編碼的'e4bda0e5a5bd',對計算機來說實際上時同一個意思。


拷貝Buffer


 將一個Buffer的內容拷貝到另一個Buffer,使用buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])。

var buf1 = Buffer.from('12345');
var buf2 = Buffer.from('6789');
buf2.copy(buf1, 2);
console.log(buf1.toString()); //12678
//buf2.copy(buf1, 2, 1, 2);
//console.log(buf1.toString()); //12745
//buf2.copy(buf1, 0);
//console.log(buf1.toString()); //67895
上例中,指將buf2的內容拷貝至buf1,targetStart表示插入buf1位置,sourceStart表示buf2的將要被復制的開始位置,sourceEnd表示buf2的將要被復制的結束位置。


裁剪Buffer


裁剪Buffer是指將已有Buffer進行拆分,取出部分可用內容,裁剪Buffer使用buf.slice([start[, end]])。

var buffer1 = Buffer.from('helloworld');
var buffer2 = buffer1.slice(0, 2);
console.log(buffer2.toString()); //he


有關Buffer的其它API,具體可以參考Node中文網的文檔。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com