1、Buffer對象
buffer對象每個元素的值爲16進制數(0-255之間),utf-8格式string轉buffer對象時,漢字佔3位,字母,符號佔1位。
給buffer通過下標賦值爲value,value大於255時會取value%256作爲結果,小於0會追加256,直到值爲0-255之間,有小數則會直接截斷小數部分,然後取0-255之間整數值。
2、安全性
3、buffer內存分配
buffer對象使用內存爲堆外內存,即在C++層面申請內存,javaScript層面分配內存。
Node爲了分配申請好的內存,採用slab動態內存分配機制,每個slab爲一塊申請好的固定大小的內存單元(Buffer.poolSize=8*1024 8KB大小)。
slab有三種狀態:
full :完全分配狀態
partial:部分分配狀態
empty:完全未分配狀態
1、分配小buffer對象:如果指定buffer對象大小小於8KB,則爲小對象分配。
申請固定分配單元slab,此時爲empty狀態。
new Buffer(1024) 分配1KB對象
new Buffer(3000) 再分配3000B對象
×如果先new Buffer(1024) 再 new Buffer(8*1024),當第二次分配對象不夠存儲在第一次預申請內存時,則會再申請一塊slab內存單元然後存放第二個對象,所以第一個對象實際大小爲1KB但卻佔用了8KB內存,可以解釋實際內存使用量一般會大於申請量的現象。只有當每個slab中的所有對象都不再被引用纔會實際釋放整個slab(8KB)資源。
2、分配大對象:指定buffer對象大於8KB,則會直接申請一塊當前所需量大小內存塊作爲一個slab單元,此slab單元由此對象獨享。
4、Buffer的轉換
讀取文件流避免中文亂碼的合理方式
const fs=require('fs');
// highWaterMark用於指定每次讀取的字節數,即chunk的大小
const readStream = fs.createReadStream('./a.txt',{highWaterMark:11});
const data=[];
let size=0;
readStream.on('data',function(chunk){
data.push(chunk);
size+=chunk.length;
});
readStream.on('end',function(){
// Buffer.concat(data,size)用於拼接小對象爲大對象,指定size時效率會更高(少了計算data實際長度的過程)當size小於實際長度時會截斷。
let buffer=Buffer.concat(data,size);
console.log(buffer.toString());
});
在網絡傳輸過程中,傳輸buffer對象,二進制流方式效率更高。