1. 程式人生 > >node.js官方文檔解析 02—buffer 緩沖器

node.js官方文檔解析 02—buffer 緩沖器

文檔 新的 如果 屬性 進行 EDA 其他 相互轉換 額外

Buffer 類的實例類似於整數數組,但 Buffer大小是固定的、且在 V8 堆外分配物理內存。Buffer 的大小在被創建時確定,且無法調整

Buffer 類在 Node.js 中是一個全局變量,因此無需使用 require(‘buffer‘).Buffer

// 創建一個長度為 10、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);
//const(常量)
//.alloc(分配/申請內存) // 創建一個長度為 10、且用 0x1 填充的 Buffer。 const buf2 = Buffer.alloc(10, 1); // 創建一個長度為 10、且未初始化的 Buffer。 // 這個方法比調用 Buffer.alloc() 更快, // 但返回的 Buffer 實例可能包含舊數據, // 因此需要使用 fill() 或 write() 重寫。 const buf3 = Buffer.allocUnsafe(10); // 創建一個包含 [0x1, 0x2, 0x3] 的 Buffer。 const buf4 = Buffer.from([1, 2, 3]); // 創建一個包含 UTF-8 字節 [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。 ??????
const buf5 = Buffer.from(‘tést‘); // 創建一個包含 Latin-1 字節 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。 const buf6 = Buffer.from(‘tést‘, ‘latin1‘);

  

//TypedArray:對象描述底層二進制數據緩沖區的類似數組的視圖。沒有一個名為TypedArray的全局屬性,也沒有直接可見的TypedArray構造器。相反,這裏有許多不同的全局屬性,它們的值是特定元素類型的類型化數組構造函數。

  • Buffer.from(array) 返回一個新建的包含所提供的字節數組的副本的 Buffer
  • [Buffer.from(arrayBuffer[, byteOffset [, length]])][Buffer.from(arrayBuffer)] 返回一個新建的與給定的 ArrayBuffer 共享同一內存的 Buffer
  • Buffer.from(buffer) 返回一個新建的包含所提供的 Buffer 的內容的副本Buffer
  • Buffer.from(string[, encoding]) 返回一個新建的包含所提供的字符串的副本的 Buffer
  • [Buffer.alloc(size[, fill[, encoding]])]Buffer.alloc() 返回一個指定大小的被填滿的 Buffer
    實例
    。 這個方法會明顯地比 Buffer.allocUnsafe(size) 慢,但可確保新創建的 Buffer 實例絕不會包含舊的和潛在的敏感數據。
  • Buffer.allocUnsafe(size)Buffer.allocUnsafeSlow(size) 返回一個新建的指定 sizeBuffer,但它的內容必須被初始化,可以使用 buf.fill(0) 或完全寫滿。

--zero-fill-buffers 命令行選項

Buffer 實例在創建時自動用 0 填充。 使用這個選項會改變這些方法的默認行為,且對性能有明顯的影響。 建議只在需要強制新分配Buffer 實例不能包含潛在的敏感數據時才使用 --zero-fill-buffers 選項。

$ node --zero-fill-buffers
> Buffer.allocUnsafe(5);
<Buffer 00 00 00 00 00>

  

—— Buffer.allocUnsafe()Buffer.allocUnsafeSlow() 不安全

當調用 Buffer.allocUnsafe()Buffer.allocUnsafeSlow() 時,被分配的內存段是未初始化的(沒有用 0 填充)。 雖然這樣的設計使得內存的分配非常快,但已分配的內存段可能包含潛在的敏感舊數據。

使用通過 Buffer.allocUnsafe() 創建的沒有被完全重寫內存的 Buffer ,在 Buffer 內存可讀的情況下,可能泄露它的舊數據。

雖然使用 Buffer.allocUnsafe() 有明顯的性能優勢,但必須額外小心,以避免給應用程序引入安全漏洞。

Buffer 與字符編碼

Buffer 實例一般用於表示編碼字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六進制編碼的數據。 通過使用顯式的字符編碼,就可以在 Buffer 實例與普通的 JavaScript 字符串之間進行相互轉換。

//UTF-8(統一資源定位符)

//UCS2(通用字符集)

//Base64(基於64編碼)

//hex(十六進制編碼)

for examle:

const buf = Buffer.from(‘hello world‘, ‘ascii‘);

// 輸出 68656c6c6f20776f726c64
console.log(buf.toString(‘hex‘));

// 輸出 aGVsbG8gd29ybGQ=
console.log(buf.toString(‘base64‘));

Node.js 目前支持的字符編碼包括:

  • ‘ascii‘ - 僅支持 7 位 ASCII 數據。如果設置去掉高位的話,這種編碼是非常快的。

  • ‘utf8‘ - 多字節編碼的 Unicode 字符。許多網頁和其他文檔格式都使用 UTF-8

  • ‘utf16le‘ - 2 或 4 個字節,小字節序編碼的 Unicode 字符。支持代理對(U+10000 至 U+10FFFF)。

  • ‘ucs2‘ - ‘utf16le‘ 的別名。

  • ‘base64‘ - Base64 編碼。當從字符串創建 Buffer 時,按照 RFC4648 第 5 章的規定,這種編碼也將正確地接受“URL 與文件名安全字母表”。

  • ‘latin1‘ - 一種把 Buffer 編碼成一字節編碼的字符串的方式(由 IANA 定義在 RFC1345第 63 頁,用作 Latin-1 補充塊與 C0/C1 控制碼)。

  • ‘binary‘ - ‘latin1‘ 的別名。

  • ‘hex‘ - 將每個字節編碼為個十六進制字符。

註意:現代瀏覽器遵循 WHATWG 編碼標準‘latin1‘ 和 ISO-8859-1 別名為 win-1252。 這意味著當進行例如 http.get() 這樣的操作時,如果返回的字符編碼是 WHATWG 規範列表中的,則有可能服務器真的返回 win-1252 編碼的數據,此時使用 latin1‘ 字符編碼可能會錯誤地解碼數據

Buffer 與 TypedArray

Buffer 實例也是 Uint8Array 實例。 但是與 [ECMAScript 2015] 中的 TypedArray 規範還是有些微妙的不同。 例如,當 ArrayBuffer#slice() 創建一個切片的副本時,Buffer#slice() 的實現是在現有的 Buffer 上不經過拷貝直接進行創建,這也使得 Buffer#slice() 更高效。

遵循以下註意事項,也可以從一個 Buffer 創建一個新的 TypedArray 實例:

  1. Buffer對象的內存拷貝到 TypedArray,而不是共享的。

  2. Buffer 對象的內存是被解析為一個明確元素的數組,而不是一個目標類型的字節數組。 也就是說,new Uint32Array(Buffer.from([1, 2, 3, 4])) 會創建一個包含 [1, 2, 3, 4] 四個元素的 Uint32Array,而不是一個只包含一個元素 [0x1020304][0x4030201]Uint32Array

也可以通過 TypeArray 對象的 .buffer 屬性創建一個新建的且與 TypedArray 實例共享同一分配內存的 Buffer

//Uint8Array (Uint8Array類型化數組代表一個8位無符號整數數組。內容被初始化為0。一旦建立,您就可以使用對象的方法來引用數組中的元素,或者使用標準的數組索引語法(也就是說,使用括號表示法)。)

node.js官方文檔解析 02—buffer 緩沖器