搜尋
首頁web前端js教程深入了解Node中的Buffer

深入了解Node中的Buffer

Apr 25, 2023 pm 07:49 PM
前端node.js

深入了解Node中的Buffer

在 Stream 篇結中,我們留下了一個問題,下述程式碼輸出的 chunk 是什麼東西?

深入了解Node中的Buffer

透過列印,我們發現 chunk 是 Buffer 對象,其中的元素是16進位的兩位數,也就是0~255的數值。 【相關教學推薦:nodejs影片教學程式設計教學

Untitled 1.png

#說明在Stream 中流動的資料就是Buffer,那以下就讓我們來探究一下Buffer 的真實面目!

? Node 中為什麼要引入Buffer?

最開始的時候JS 只在瀏覽器端運行,對於Unicode 編碼的字串容易處理,但是對於二進制和非Unicode 編碼的字串處理困難。而二進制是電腦最底層的資料格式,視訊/音訊/程式/網路包都是以二進位來儲存的。所以 Node 需要引入一個物件來操作二進位,因此 Buffer 誕生了,用於 TCP流/檔案系統等操作處理二進位位元組。

由於Buffer 在Node 中過於常用,所以在Node 啟動的時候已經引入了Buffer,無需使用require()

ArrayBuffer

是什麼

ArrayBuffer 是內存之中的一段二進位數據,本身不能夠操作內存,需要透過TypedArray 物件DataView 來操作。將緩衝區中的資料表示為特定的格式,並透過這些格式來讀寫緩衝區的內容,其部署了數組接口,可以使用數組的方式來操作資料

TypedArray 視圖

最常用的是TypeArray 視圖,用來讀寫簡單類型的ArrayBuffer,例如Uint8Array(無符號8位元整數)陣列視圖, Int16Array(16位元整數)陣列視圖

和Buffer 的關係

NodeJS 中的Buffer 類別其實是Uint8Array 的實作。

Buffer 結構

Buffer 是一個類似Array 的對象,但是它主要用於操作位元組

模組結構

Buffer 是JS 和C 結合的模組,性能部分都由C 實現,非性能部分都是JS 實現的Untitled 2.png

Buffer 所佔用的記憶體不是由V8 分配的,屬於堆外記憶體。

物件結構

Buffer 物件類似數組,其元素為16進位的兩位數,即0~255的數值

Untitled 3.png

#從這個例子能夠看出,不同字元在Buffer 中佔據的位元組是不一樣的,在UTF-8 編碼下,中文佔據3個字節,英文和半角標號佔用1個位元組

? 輸入的元素是小數/負數/超出255會發生什麼事?

Untitled 4.png

對於上述這種情況,Buffer 的處理為:

  • 給元素的賦值小於0, 就將該值逐次加256,直到得到一個0到255之間的整數
  • 如果得到的數值大於255,就逐次減256,直到得到0~255區間內的數值
  • 如果是小數,只保留整數部分

Buffer 裡面為什麼展示的是16進位

其實在記憶體儲存的依舊是二進制數,只是Buffer 在顯示這內存資料的時候採用了16進位

大小為2位元組的buffer,一共有16 bit ,例如是00000001 00100011,如果直接這樣顯示不太方便就轉成為了16進位<buffer></buffer>

Buffer 的建立

Buffer.alloc 與Buffer.allocUnsafe

# 建立固定大小的buffer

Buffer.alloc(size [, fill [, encoding]])

  • size 新 Buffer 的所需長度
  • fill 用於預先填入新 Buffer 的值。預設值: 0
  • encoding 如果 fill 是一個字串,則這是它的字元編碼。預設值: utf8

Untitled 5.png

Buffer.allocUnsafe(size)

分配一個大小為size 位元組的Buffer,allocUnsafe 執行速度比alloc 快,我們發現其結果並不像Buffer.alloc 那樣都初始化為00

Untitled 6.png

#當呼叫allocUnsafe 時分配的記憶體段尚未初始化,這樣分配記憶體速度很塊,但分配到的記憶體片段可能包含舊資料。如果使用的時候不覆寫這些舊資料就可能造成記憶體洩露,雖然速度快,盡量避免使用

Buffer 模組會預先分配一個內部的大小為 Buffer.poolSize 的Buffer 實例,作為快速分配的記憶體池,用於使用allocUnsafe 建立新的Buffer 實例

Buffer.from

根據內容直接建立Buffer

  • Buffer.from(string [, encoding] )
  • Buffer.from(array)
  • Buffer.from(buffer)

Untitled 7.png

##Buffer.allocUnsafe 的記憶體機制

為了有效地使用申請來的內存,Node.js 採用了slab 機制進行預先申請、事後分配,是一種動態的管理機制

使用 Buffer.alloc(size) 傳入一個指定的 size 就會申請一塊固定大小的記憶體區域,slab 有以下三種狀態

    full: 完全分配狀態
  • partial:部分分配狀態
  • # empty:沒有被指派狀態
Node.js 使用8 KB 為界限來區分是小物件還是大物件

Untitled 8.png

Buffer在創建的時候大小就已經被確定了且無法調整!

分配小物件

如果分配的物件小於8KB,Node 會以小物件的方式來進行分配

Buffer 的分配過程中主要使用一個局部變數 pool 作為中間處理對象,處於分配狀態的 slab 單元都指向它。以下是指派一個全新的slab 單元的操作,它將新申請的SlowBuffer 物件指向它

Untitled 9.png

一個slab 單元

Untitled 10.png

分配一個2KB 大小的Buffer

建立一個2KB 的buffer後,一個slab 單元記憶體如下:

Untitled 11.png

這個分配過程是由allocate方法完成

Untitled 12.png

當我們建立了一個2KB 的buffer 之後,目前slab 狀態為partial

再次建立buffer 的時候,會去判斷目前slab 剩餘空間是否足夠。如果足夠,使用剩餘空間,並更新slab 的分配狀態

如果slab 空間不夠,就會建構新的slab,原slab 中剩餘的空間造成浪費

分配大物件

如果有超過8KB 的buffer,直接會走到creatUnsafeBuffer 函數,分配一個slab 單元,這個slab 單元將會被這個大Buffer 物件獨佔

allocate 分配機制如圖

Untitled 13.png

#Buffer 的記憶體分配機制

Untitled 14.png

#Buffer 和字元編碼

透過使用字元編碼,可實現Buffer 實例與JavaScript 字串之間的相互轉換

Untitled 15.png

Node 中目前支援utf8、ucs2、utf16le、latin1、ascii、base64、hex、base64Url 八種編碼方式,具體實作

Untitled 16.png

#針對於每一種不同的編碼方案都會用實作一系列api,傳回會有不同的結果,Node.js 會根據傳入的encoding 來傳回不同的物件

Buffer 和字串的轉換

字串轉Buffer

主要透過上述講的Buffer.from 方法,預設的encoding 方式為utf-8

Buffer 轉字串

Untitled 17.png

#? 為什麼會出現亂碼呢?如何解決這個問題呢?

按著讀取來說,我們每次讀取的長度為4,chunk輸出如下

Untitled 18.png

#對於data = chunk等價於data = data.toString chunk.toString

#由於一個中文佔據三個字節,第一個chunk 中的第四個位元組會顯示亂碼,第二個chunk 的第一第二個位元組也無法形成文字等等,所以會展示亂碼問題

更多node相關知識,請造訪:nodejs 教學

以上是深入了解Node中的Buffer的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:掘金社区。如有侵權,請聯絡admin@php.cn刪除
JavaScript數據類型:瀏覽器和nodejs之間是否有區別?JavaScript數據類型:瀏覽器和nodejs之間是否有區別?May 14, 2025 am 12:15 AM

JavaScript核心數據類型在瀏覽器和Node.js中一致,但處理方式和額外類型有所不同。 1)全局對像在瀏覽器中為window,在Node.js中為global。 2)Node.js獨有Buffer對象,用於處理二進制數據。 3)性能和時間處理在兩者間也有差異,需根據環境調整代碼。

JavaScript評論:使用//和 / * * / * / * /JavaScript評論:使用//和 / * * / * / * /May 13, 2025 pm 03:49 PM

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python vs. JavaScript:開發人員的比較分析Python vs. JavaScript:開發人員的比較分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。