js
起初就是爲瀏覽器而設計的,因此能很好的處理unicode
編碼的字符串,但不能很好的處理二進制數據。這是Node.js
的一個問題,由於Node.js
旨在網絡上發送和接收常常是以二進制格式傳輸的數據。好比:node
- 經過TCP鏈接發送和接收數據; - 從圖像或者壓縮文件讀取二進制數據; - 從文件系統讀寫數據; - 處理來自網絡的二進制數據流
而Buffer
模塊爲Node.js
帶來了一種存儲原始數據的方法,因而能夠再js
的上下文中使用二進制數據。每當須要在Node.js
中處理I/O
操做中移動的數據時,就有可能使用Buffer模塊。數組
Buffer
類是一個全局變量類型,用來直接處理2進制數據的。 它可以使用多種方式構建。瀏覽器
原始數據保存在 Buffer
類的實例中。一個 Buffer
實例相似於一個整數數組網絡
1.new Buffer(size):分配一個新的 buffer 大小是 size 的8位字節. 2.new Buffer(array):分配一個新的 buffer 使用一個8位字節 array 數組. 3.new Buffer(str, [encoding]):encoding String類型 - 使用什麼編碼方式,參數可選. 4.類方法: Buffer.isEncoding(encoding):若是給定的編碼 encoding 是有效的,返回 true,不然返回 false。 5.類方法: Buffer.isBuffer(obj):測試這個 obj 是不是一個 Buffer. 返回Boolean 6.類方法: Buffer.concat(list, [totalLength]):list {Array}數組類型,Buffer數組,用於被鏈接。totalLength {Number}類型 上述Buffer數組的全部Buffer的總大小。
除了能夠讀取文件獲得Buffer
的實例外,還可以直接構造,例如:測試
var bin = new Buffer([ 0x48, 0x65, 0x6c, 0x6c, 0x6c ]);
Buffer
與字符串相似,除了能夠用.length
屬性獲得字節長度外,還能夠用[index]
方式讀取指定位置的字節,例如:ui
bin[0]; // => 0x48;
Buffer
與字符串可以互相轉化,例如可使用指定編碼將二進制數據轉化爲字符串:this
var str = bin.toString('utf-8'); // => "hello"
.slice
方法不是返回一個新的Buffer
,而更像是返回了指向原Buffer
中間的某個位置的指針,以下所示。編碼
1.[ 0x48, 0x65, 0x6c, 0x6c, 0x6c ] 2. ^ ^ 3. | | 4. bin bin.slice(2)
var buffer = new Buffer(8);//建立一個分配了8個字節內存的緩衝區 console.log(buffer.write('a','utf8'));//輸出1
這會將字符"a"
寫入緩衝區,node
返回通過編碼之後寫入緩衝區的字節數量,這裏的字母a
的utf-8
編碼佔用1個字節。操作系統
Node.js
提供了一個將Buffer
對象總體內容複製到另外一個Buffer
對象中的方法。咱們只能在已經存在的Buffer
對象之間複製,因此必須建立它們。設計
buffer.copy(bufferToCopyTo)
其中,bufferToCopyTo
是要複製的目標Buffer對象。以下示例:
var buffer1 = new Buffer(8); buffer1.write('nice to meet u','utf8'); var buffer2 = new Buffer(8); buffer1.copy(buffer2); console.log(buffer2.toString());//nice to meet u
在UNIX
類型的操做系統中,流是個標準的概念。有以下三個主要的流:
1.標準輸入 2.標準輸出 3.標準錯誤
若是說,緩衝區是Node.js
處理原始數據的方式的話,那麼流一般是Node.js
移動數據的方式。Node.js
中的流是可讀的或者可寫的。Node.js
中許多模塊都使用了流,包括HTTP
和文件系統。
假設咱們建立一個classmates.txt
的文件,並從中讀入姓名清單,以便使用這些數據。因爲數據是流,這就意味着完成文件讀取以前,從收到最初幾個字節開始,就能夠對數據動做,這是Node.js
中的一個常見模式:
var fs = require('fs'); var stream = fs.ReadStream('classmates.txt'); stream.setEncoding('utf8'); stream.on('data', function (chunk) { console.log('read some data') }); stream.on('close', function () { console.log('all the data is read') });
在以上示例中,在收到新數據時觸發事件數據。當文件讀取完成後觸發關閉事件。
顯然,咱們也能夠建立可寫流以便寫數據。這意味着,只要一段簡單的腳本,就可使用流讀入文件而後寫入另外一個文件:
var fs = require('fs'); var readableStream = fs.ReadStream('classmates.txt'); var writableStream = fs.writeStream('names.txt'); readableStream.setEncoding('utf8'); readableStream.on('data', function (chunk) { writableStream.write(chunk); }); readableStream.on('close', function () { writableStream.end(); });
如今,當接收到數據事件時,數據會被寫入可寫流中。
readable.setEncoding(encoding):返回: this readable.resume():同上。該方法讓可讀流繼續觸發 data 事件。 readable.pause():同上。該方法會使一個處於流動模式的流中止觸發 data 事件,切換到非流動模式,並讓後續可用數據留在內部緩衝區中。
Writable
(可寫)流接口是對您正在寫入數據至一個目標的抽象。
1.writable.write(chunk, [encoding], [callback]): chunk {String | Buffer} 要寫入的數據 encoding {String} 編碼,假如 chunk 是一個字符串 callback {Function} 數據塊寫入後的回調 返回: {Boolean} 若是數據已被所有處理則 true。
該方法向底層系統寫入數據,並在數據被處理完畢後調用所給的回調。
2.writable.cork():強行滯留全部寫入。
滯留的數據會在 .uncork()
或 .end()
調用時被寫入。
3.writable.end([chunk], [encoding], [callback]) chunk {String | Buffer} 可選,要寫入的數據 encoding {String} 編碼,假如 chunk 是一個字符串 callback {Function} 可選,流結束後的回調
在調用 end()
後調用 write()
會產生錯誤。
// 寫入 'hello, ' 而後以 'world!' 結束 http.createServer(function (req, res) { res.write('hello, '); res.end('world!'); // 如今不容許繼續寫入了 });