node.js教學-什麼是Buffer物件?

8 / 9, 2013 JS , node.js , 網路

這是node.js教學的第四篇  (這次教學文又遲了,因為和Allen一起弄LA WebTop……)

繼上次教學文-怎樣使用node.js檔案系統的時候便說了

fs.readFile

回傳的結果並不是

String

而是

Buffer

物件,現在就是說為什麼了。 其實我們電腦裡有很多檔案其實不是文字檔案來的。實際上,大部分我們開啟的檔案都是二進制檔案,例如圖片檔案,音訊檔案,簡報等等…… 而且,所有檔案裡的資料其實都是以二進制表示的。所以我們就用Buffer物件去表示檔案的內容,和方便我們閱讀檔案資料的每個位元組。

還有,因為JS這個語言沒有一個正統的閱讀二進制資料的方法(PHP的

String

是以二進制方式儲存的,而JS的

String

是以UTF-8編碼儲存的,而JS的

String

可能會把二進制資料不正確地儲存)。所以,Buffer物件出現了!

Buffer物件就好像一個陣列,裡面有一大堆資料,每一個陣列元素都是代表了一個位元組。除了這些以外,還有一系列函數可以用來處理二進制資料。看看以下的程式:

var fs = require('fs');
fs.readFile('./file',function(err, data){
    //data是一個Buffer物件
    console.log("是否Buffer物件?", Buffer.isBuffer(data)); //true

    //獲取Buffer大小
    //注意這不一定是資料的總長度,只是代表了
    //Buffer在記憶體中的總大小,即使更改Buffer物件的資料,
    //這個數值仍然不會改變。
    console.log("Buffer大小:", data.length);

    //獲取資料頭十個位元組
    //注意:如果修改這個Buffer物件的資料,原來那個
    //Buffer物件的資料也會被修改
    var first10bytes = data.slice(0,10);
    console.log(first10bytes); // <Buffer 00 00 00 00 00 00 00 00 00 00>

    //寫入資料
    data.write('I love node.js', 0, 14);

    //first10bytes的資料也會隨著變動,
    //因為這兩個Buffer物件都是指向同一個記憶體位置
    console.log(first10bytes); // <Buffer 49 20 6c 6f 76 65 20 6e 6f 64>
});

//我們也可以自己建立Buffer物件
//Buffer物件感覺上有點和C的 malloc(size) 相似
var buf = new Buffer(256);

//也可以給他String,把它變成Buffer物件
var buf = new Buffer('I love node.js !!!!!!!!!!!!!!!!!!!!');
//還可以設定字元集,預設utf-8
var buf = new Buffer('I love node.js !!!!!!!!!!!!!!!!!!!!', 'ascii');
//更可以Base64 decode
var buf = new Buffer('SSBsb3ZlIG5vZGUuanMh', 'base64'); // <Buffer 49 20 6c 6f 76 65 20 6e 6f 64 65 2e 6a 73 21>

//想把Buffer物件變成String?只要呼叫
//Buffer.toString() 就可以了
buf.toString(); // I love node.js
//還可以指定字元集,預設utf-8
buf.toString('ascii');
//更可以Base64 Encode
buf.toString('base64'); //SSBsb3ZlIG5vZGUuanMh
//可以只把部分的資料變成String
buf.toString('utf-8',0,10); //I love nod

Buffer物件有很多用途,不過主要都是處理二進制資料的。現在我會重溫剛才用到的函數:

  1. Buffer.isBuffer(obj)

    這是用來測試指定的物件是不是一個

    Buffer

    物件,如果是的,就會返回true,否則返回false。
    範例:

    Buffer.isBuffer(new Buffer(10)); //true

    範例:

    Buffer.isBuffer('123456789'); //false
  2. buf.length這是一件Buffer物件的大小,注意這不一定是資料的總長度,只是代表了Buffer在記憶體中的總大小。
  3. buf.slice(start, end)

    這是用來把一個

    Buffer

    物件分割的,並會返回一件新的Buffer物件。
    注意:返回的

    Buffer

    物件仍然是指向同一個記憶體位置,所以修改這個

    Buffer

    物件的資料也會同時修改原來那個Buffer物件的資料。
    範例:

    var buf2 = buf.slice(0, 10);

    範例:

    var buf2 = buf.slice(); //把整個Buffer複製,不過還是指向同一個記憶體位置
  4. buf[index]

    這個其實就和陣列一樣。index就是每個位元組的資料。
    範例:

    var buf = new Buffer('I love node.js'); console.log(String.fromCharCode(buf[0])); // I
  5. buf.write(data, [offset], [length])

    把資料寫入特定的位置。

  6. new Buffer(size)

    建立一個空的

    Buffer

    物件。

  7. new Buffer(str, [encoding])

    建立一個

    Buffer

    物件,以str為

    Buffer

    物件的資料。
    字元集可以不用設定,預設utf-8(把這個變成base64就可以作Base64 Decode了)

  8. buf.toString([encoding], [offset], [length])

    把一個

    Buffer

    物件變成

    String

    字元集可以不用設定,預設utf-8。(把這個變成base64就可以作Base64 Encode了)

    offset

    是開始位置,而

    length

    就是資料的長度。可以不用設定,就會把整個

    Buffer

    物件轉換。

其實Buffer物件不止這些的,還有一些函數用來寫入和讀取位元組的(不過我怕大家會不明白那些Big Endian,Little Endian,Uint8……的東西),所以就不介紹了…… 如果想知道的話,你可以看看node.js的說明

下一回node.js教學就是說說怎樣在node.js使用MySQL囉!