node.js官方文檔解析 02—buffer 緩沖器
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)
返回一個新建的指定size
的Buffer
,但它的內容必須被初始化,可以使用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
實例:
-
Buffer
對象的內存是拷貝到TypedArray
的,而不是共享的。 -
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 緩沖器