目錄
ArrayBuffer
是什麼
TypedArray 視圖
和Buffer 的關係
Buffer 結構
模組結構
物件結構
Buffer 的建立
Buffer.alloc 與Buffer.allocUnsafe
Buffer.alloc(size [, fill [, encoding]])
Buffer.allocUnsafe(size)
Buffer.from
Buffer 和字串的轉換
字串轉Buffer
Buffer 轉字串
首頁 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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

PHP與Vue:完美搭檔的前端開發利器 PHP與Vue:完美搭檔的前端開發利器 Mar 16, 2024 pm 12:09 PM

PHP與Vue:完美搭檔的前端開發利器在當今網路快速發展的時代,前端開發變得愈發重要。隨著使用者對網站和應用的體驗要求越來越高,前端開發人員需要使用更有效率和靈活的工具來創建響應式和互動式的介面。 PHP和Vue.js作為前端開發領域的兩個重要技術,搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結合,以及詳細的程式碼範例,幫助讀者更好地理解和應用這兩

如何使用 Go 語言進行前端開發? 如何使用 Go 語言進行前端開發? Jun 10, 2023 pm 05:00 PM

隨著網路技術的發展,前端開發變得日益重要。尤其是行動端設備的普及,更需要高效率、穩定、安全又易於維護的前端開發技術。而作為一門快速發展的程式語言,Go語言已經被越來越多的開發者所使用。那麼,使用Go語言進行前端開發行得通嗎?接下來,本文將為你詳細說明如何使用Go語言進行前端開發。先來看看為什麼要使用Go語言進行前端開發。很多人認為Go語言是一門

前端面試官常問的問題 前端面試官常問的問題 Mar 19, 2024 pm 02:24 PM

在前端開發面試中,常見問題涵蓋廣泛,包括HTML/CSS基礎、JavaScript基礎、框架和函式庫、專案經驗、演算法和資料結構、效能最佳化、跨域請求、前端工程化、設計模式以及新技術和趨勢。面試官的問題旨在評估候選人的技術技能、專案經驗以及對行業趨勢的理解。因此,應試者應充分準備這些方面,以展現自己的能力和專業知識。

Django是前端還是後端?一探究竟! Django是前端還是後端?一探究竟! Jan 19, 2024 am 08:37 AM

Django是一個由Python編寫的web應用框架,它強調快速開發和乾淨方法。儘管Django是web框架,但要回答Django是前端還是後端這個問題,需要深入理解前後端的概念。前端是指使用者直接和互動的介面,後端是指伺服器端的程序,他們透過HTTP協定進行資料的互動。在前端和後端分離的情況下,前後端程式可以獨立開發,分別實現業務邏輯和互動效果,資料的交

golang可以做前端嗎 golang可以做前端嗎 Jun 06, 2023 am 09:19 AM

golang可以做前端,Golang是一種通用性很強的程式語言,可以用於開發不同類型的應用程序,包括前端應用程序,透過使用Golang來編寫前端,可以擺脫JavaScript等語言引起的一系列問題,例如類型安全性差、效能低下,以及程式碼難以維護等問題。

C#開發經驗分享:前端與後端協同開發技巧 C#開發經驗分享:前端與後端協同開發技巧 Nov 23, 2023 am 10:13 AM

身為C#開發者,我們的開發工作通常包括前端和後端的開發,而隨著技術的發展和專案的複雜性提高,前端與後端協同開發也變得越來越重要和複雜。本文將分享一些前端與後端協同開發的技巧,以幫助C#開發者更有效率地完成開發工作。確定好介面規範前後端的協同開發離不開API介面的交互。要確保前後端協同開發順利進行,最重要的是定義好介面規格。接口規範涉及到接口的命

Go語言前端技術探秘:前端開發新視野 Go語言前端技術探秘:前端開發新視野 Mar 28, 2024 pm 01:06 PM

Go語言作為一種快速、高效的程式語言,在後端開發領域廣受歡迎。然而,很少有人將Go語言與前端開發聯繫起來。事實上,使用Go語言進行前端開發不僅可以提高效率,還能為開發者帶來全新的視野。本文將探討使用Go語言進行前端開發的可能性,並提供具體的程式碼範例,幫助讀者更了解這一領域。在傳統的前端開發中,通常會使用JavaScript、HTML和CSS來建立使用者介面

Golang與前端技術結合:探討Golang如何在前端領域發揮作用 Golang與前端技術結合:探討Golang如何在前端領域發揮作用 Mar 19, 2024 pm 06:15 PM

Golang與前端技術結合:探討Golang如何在前端領域發揮作用,需要具體程式碼範例隨著互聯網和行動應用的快速發展,前端技術也愈發重要。而在這個領域中,Golang作為一門強大的後端程式語言,也可以發揮重要作用。本文將探討Golang如何與前端技術結合,以及透過具體的程式碼範例來展示其在前端領域的潛力。 Golang在前端領域的角色作為一門高效、簡潔且易於學習的

See all articles