Node---Buffer

目錄

Buffer出現解決了什麼問題

Buffer與String在使用上的區別

Buffer內存

Buffer的出現解決了什麼問題

  1. 解決了JavaScript在處理二進制流方面的軟肋。例如流和文件操作,因爲與操作系統或其它進程的交互總是以二進制數據的形式發生。
  2. 可以突破Node內存限制,可以更大範圍使用內存。

區別

# 聲明
let str = 'xxx'; // String可以直接使用字面量聲明
let buf1 = Buffer.from('xxx') // Buffer 需要通過Buffer.from來創建

# 拼接
let str3 = `str1:${ str1 }str2:${ str2 }`;
let buf3 = Buffer.concat([buf1, buf2], buf1.length + buf2.length);

# 性能
由於buffer是二進制數據,而string是字符串數據,在網絡傳輸過程中是以二進制流進行傳輸的,所以buffer的傳輸效率較string會略勝一籌。

# 注意,buffer也會產生亂碼,在使用createReadStream讀取字節流的時候,由於data太大,所以導致分爲多次傳輸,中間存在截斷的現象。爲了在拼接的過程中不產生亂碼,提供以下兩種方法
 - 將所有的數據讀取以後,然後再拼接buffer,最後使用三方庫iconv-lite轉碼
 - 再獲取到buffer數據的時候,使用bufferData.setEncoding('utf8');// 其實內部是使用了string_decoder
這兩種方法有一個區別,第一種方法是獲取所有的buffer後再拼接,然後轉碼,而第二種方法是獲取多少轉多少。

內存管理

Buffer對象的內存分配不是在V8的堆內存中,而是在Node的C++層面實現內存的申請中。因爲處理大量的字節數據不能採用需要一點內存就向OS申請一點內存的方式,這可能造成大量內存申請的系統調用,對OS有一定壓力。

在Node裏面,默認將Buffer分爲兩種對象:數據大於8 * 1024字節的大對象和小於 8 * 1024 的小對象。

# 創建兩個大對象變量,兩次申請內存
let buf1 = Buffer.alloc(8200);
let buf1 = Buffer.alloc(8200);

# 創建兩個小對象,一次內存申請
let buf2 = Buffer.alloc(10);
let buf3 = Buffer.alloc(100);

同樣是兩次變量申請,前者兩次系統調用,後者一次系統調用。原因是內部有一個控制內存申請的閾值,默認是 8 * 1024,可以通過Buffer.poolSize進行調整。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章