NodeJS Buffer 理解

2023/09/09閱讀時間約 7 分鐘

最近跟著影片學習NodeJS,第一部分先學習對Buffer的處理跟理解,以下是對於NodeJS Buffer的理解筆記

Buffer是什麼?

根據線上教學文檔解釋,JavaScript 語言自身只有字符串數據類型,沒有二進制數據類型。

但在處理像TCP流或文件流時,必須使用到二進制數據。因此在 Node.js中,定義了一個 Buffer 類,該類用來創建一個專門存放二進制數據的緩存區。

而 Buffer 類提供一些使用方法,它允許你在Node.js 中直接操作二進制數據,而不需要像在瀏覽器中使用JavaScript時那樣使用字串。 Buffer類提供了一種在內存中存儲和操作二進制數據的方式,這對於處理文件、網絡數據、加密和解密等任務非常有用。

Buffer的應用

以下是Buffer的一些常見用途和特性:

1. 二進制數據儲存:你可以使用Buffer來存儲二進制數據,如文件內容、網絡數據、圖像、音頻等。

2. 數據轉換:Buffer可以輕鬆地將不同編碼的數據相互轉換,例如將字串轉換為二進制數據或將二進制數據轉換為字串。

3. 文件操作:Node.js的文件系統模塊(fs)通常使用Buffer來讀取和寫入文件內容,這是文件I/O操作的常見方式。

4. 網絡通信:Buffer在處理網絡數據時非常重要,它可以用於構建和解析HTTP請求、WebSocket數據等。

5. 加密和解密:許多加密算法(如AES、RSA等)操作的輸入和輸出數據通常是Buffer類型。

6. 性能優勢:與字串相比,Buffer在處理大量數據時通常具有更高的性能,因為它不需要解析字符編碼。

Buffer的內建方法函式

在NodeJS中提供了三種操作Buffer的函數,分別是Buffer.alloc()Buffer.allocUnsafeBuffer.from()

Buffer.alloc(size[, fill[, encoding]]): 返回一個指定大小的 Buffer 實例,如果沒有設置 fill,則默認填滿 0

以下是 Buffer.alloc 的基本用法:

let buf = Buffer.alloc(10);
console.log(buf);
raw-image

Buffer.allocUnsafe(size): 返回一個指定大小的 Buffer 實例,但是它不會被初始化,所以它可能包含敏感的數據。

而這裡創建 Buffer.allocUnsafe 速度執行會比 Buffer.alloc 快,主要是因為使用allocUnsafe 容易包含舊數據或是隨機的內容,故在使用時要確保洩漏敏感數據而導致不可預測的問題。

以下是 Buffer.allocUnsafe(size) 的基本用法:

const size = 10; 
const buffer = Buffer.allocUnsafe(size);
console.log(buffer);

Buffer.from()

而根據教學文檔來說,會較推薦使用Buffer.from()來創建。它允許你從不同的數據源創建 Buffer 對象。 Buffer.from() 方法通常用於將其他數據類型(如字串、陣列或 ArrayBuffer)轉換為 Buffer。這個方法提供了一種方便的方式來處理不同數據類型之間的轉換。

let buf_3 = Buffer.from('hello'); 
console.log(buf_3);

//run node.js 結果 ➜ nodeJs node hello.js
<Buffer 68 65 6c 6c 6f>

這每一個字母都會轉換為 unicode 碼表中對應的數字,然後再轉成二進制存到buffer中,亦可透過傳遞一個陣列方式轉成二進制存到buffer

let buf_4 = Buffer.from([104, 101, 108, 108, 111]); 
console.log(buf_4);

Buffer的操作跟字串轉換

當我們使用陣列方式傳遞,並透過toString()函式,就可以將陣列中的數字轉為原來的hello格式,而這裡的toString 默認是按照 utf-8 編碼方式進行轉換的

let buf_4 = Buffer.from([104, 101, 108, 108, 111]); 
console.log(buf_4.toString()); //默認使用 utf-8 的編碼方式

Buffer的讀寫

這邊我們可以透過陣列 []取值,來對 buffer做操作。

let buf = Buffer.from('hello');
//假設我們想獲取buffer 第一個h字母buffer保存的數據

console.log(buf[0]);

//會出現104,而這裡是一個十進制的表達方式
//然後我們對於這個104做二進制的轉換

let buf = Buffer.from('hello');
console.log(buf[0].toString(2)); //這個toString的用法與上面不同,最後應該是01101000

//會出現 1101000

//對裡頭單一字母進行修改
buf[0] = 95;
console.log(buf);

➜ nodeJs node hello.js
<Buffer 5f 65 6c 6c 6f>

//結果改完第一個字母會變成5f,之前是68

Buffer補充說明

溢出:主要原因是程序未能正確地驗證輸入數據的大小,導致數據超出了緩衝區的邊界而覆蓋了相鄰的內存區域。每個元素都是一個字節,而其值的範圍應該在0到255之間。

以下是一個範例,這邊我們將值設定為361,而 buffer 二進制位能儲存的最大十進制數字為 255 而這種情況在執行時,系統會捨棄高於八進制的數字


let buf = Buffer.from('hello');
buf[0] = 361;

console.log(buf);

現在他變成69 ➜ nodeJs node hello.js
<Buffer 69 65 6c 6c 6f>

十進制 361 變成二進制為 0001 0110 1001,而當寫入時只寫入 0110 1001,透過console.log(buf); 現在他變成69

來看一下小工具執行的圖,這邊輸入十進位361,得出二進位0001 0110 1001

raw-image

接著我們捨棄高於八進制的數字,只輸入 0110 1001,利用工具二進位得輸入110 1001,這可以看到八進位結果為69,與程式碼console.log(buf)結果一致。

raw-image

以上是對學習NodeJs Buffer的理解跟用法,相關參考文件跟資料整理下方

https://www.runoob.com/nodejs/nodejs-buffer.html

軟體為ASCII Converter





13會員
37內容數
學涯無止境,透過每日or每週模仿學習筆記,不管是哪些領域也好,總有一天也可以從菜雞變小雞
留言0
查看全部
發表第一個留言支持創作者!