NodeJSBuffer對象

首先Node對字符串的支持十分的友好,無論是單字節還是多字節都被認爲是一個字符串。之所以需要Buffer對象,是因爲JavaScript本身自有的字符串對前端操作可以滿足,但是面對後臺的操作例如操作DB,處理網絡協議,文件上傳等還需要處理大量二進制數據時,JavaScript自身的字符串時無法滿足這種需求的。

1. Buffer的初識

Buffer是一個像Array的對象,主要用於操作字節,Buffer是C++與JavaScript結合的產物,對於性能方面採用C++,非性能方面採用JavaScript,之前咱們提到過Buffer是堆外內存,不是有V8分配的,因爲是常用模塊所以Node在啓動時會自動加載,並掛載到global對象上,所以在使用的時候無需require引入。

var buffer = new Buffer(length);

2. Buffer的內存管理

首先Buffer真正的內存時在C++層面上進行的申請,在JavaScript層面上使用,如果用一點內存去申請一點的話,儘管是合理的方式,但是這樣會造上內存調用上的性能消耗,所以對於Buffer而言Node採用的是動態內存管理(slab),同時Buffer區分大/小對象,以8k大小爲界限(8*1024),也就是slab的存儲單位,在內存分配上,如果是1slab不足以存儲一個對象則會創建一個新的單位,在新的單位裏進行存儲,之前未存滿的單元會被之前的小對象獨佔。

3. Buffer的轉化

· String=>Buffer

  buffer.wirte(string, [offset], [length], [encoding]);

· Buffer=>String

  buffer.toString([encoding], [start], [end]);

* 並不是所有的編碼類型在Buffer中都支持轉化,可以用Buffer.IsEncoding(encoding)來判斷是否支持,如果不支持可以用生態圈中的其他模塊來解決。

3. 對於亂碼的解決方案

// 拼接
var chunks = [];
var size = 0;
res.on('data', function(chunk){
    chunks.push(chunk);
    size += chunk.length;
});
res.on('end', function(){
    var buffer = Buffer.contat(chunks, size);
    var str = iconv.decode(buffer, 'utf-8');
    console.info(str);
});

// 圍觀一下細膩的Buffer.contact()
Buffer.concat = function(list, length){
    if(!Array.isArray(list)){
        thorw new Error('error');
    }
    if(list.length === 0){
        return new Buffer(0)
    }else if(list.length === 1){
        return list[0];
    }
    if(typeof(length !== 'number'){
        length = 0;
        for(var i = 0 ; i < list.length; i++){
            var buf = list[i];
            length += buf.length;
        }
    }

    var buffer = new Buffer(length);
    var pos = 0;
    for(var i = 0; i < list.length; i++){
        var buf = list[i];
        buf.copy(buffer, pos);
        pos += buf.length;
    }
    return buffer;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章