天天看點

Nodejs進階:核心子產品Buffer常用API使用總結

buffer是node的核心子產品,開發者可以利用它來處理二進制資料,比如檔案流的讀寫、網絡請求資料的處理等。

buffer的api非常多,本文僅挑選 比較常用/容易了解 的api進行講解,包括buffer執行個體的建立、比較、連接配接、拷貝、查找、周遊、類型轉換、截取、編碼轉換等。

new buffer(array)

buffer.alloc(length)

buffer.allocunsafe(length)

buffer.from(array)

驗證下:

例子一:buffer.from(array)

例子二:buffer.from(string[, encoding])

通過string建立buffer,跟将buffer轉成字元串時,記得編碼保持一緻,不然會出現亂碼,如下所示。

對亂碼的分析如下:

例子三:buffer.from(buffer)

建立新的buffer執行個體,并将buffer的資料拷貝到新的執行個體子中去。

判斷兩個buffer執行個體存儲的資料是否相同,如果是,傳回true,否則傳回false。

同樣是對兩個buffer執行個體進行比較,不同的是:

可以指定特定比較的範圍(通過start、end指定)

傳回值為整數,達标buf、target的大小關系

假設傳回值為

<code>0</code>:buf、target大小相同。

<code>1</code>:buf大于target,也就是說buf應該排在target之後。

<code>-1</code>:buf小于target,也就是說buf應該排在target之前。

看例子,官方的例子挺好的,直接貼一下:

跟 <code>buf.compare(target)</code> 大同小異,一般用于排序。直接貼官方例子:

這裡稍微研究下buffer.from(array)。下面是官方文檔對api的說明,也就是說,每個array的元素對應1個位元組(8位),取值從0到255。

allocates a new buffer using an array of octets.

首先看下,傳入的元素為數字的場景。下面分别是10進制、8進制、16進制,跟預期中的結果一緻。

再看下,傳入的元素為字元串的場景。

<code>0</code>開頭的字元串,在parseint('062')時,可以解釋為62,也可以解釋為50(八進制),這裡看到采用了第一種解釋。

字元串的場景,跟parseint()有沒有關系,暫未深入探究,隻是這樣猜想。todo(找時間研究下)

感興趣的同學自行探究。

一開始不自覺的會将<code>buffer.from('1')[0]</code>跟<code>"1"</code>劃等号,其實<code>"1"</code>對應的編碼是49。

這樣對比就知道了,編碼為1的是個控制字元,表示 start of heading。

備注:個人覺得<code>totallength</code>這個參數挺多餘的,從官方文檔來看,是處于性能提升的角度考慮。不過内部實作也隻是周遊list,将length累加得到totallength,從這點來看,性能優化是幾乎可以忽略不計的。

除了上面提到的性能優化,totallength還有兩點需要注意。假設list裡面所有buffer的長度累加和為length

totallength &gt; length:傳回長度為totallength的buffer執行個體,超出長度的部分填充0。

totallength &lt; length:傳回長度為totallength的buffer執行個體,後面部分舍棄。

使用比較簡單,如果忽略後面三個參數,那就是将buf的資料拷貝到target裡去,如下所示:

另外三個參數比較直覺,直接看官方例子

跟數組的查找差不多,需要注意的是,value可能是string、buffer、integer中的任意類型。

string:如果是字元串,那麼encoding就是其對應的編碼,預設是utf8。

buffer:如果是buffer執行個體,那麼會将value中的完整資料,跟buf進行對比。

integer:如果是數字,那麼value會被當做無符号的8位整數,取值範圍是0到255。

另外,可以通過<code>byteoffset</code>來指定起始查找位置。

直接上代碼,官方例子妥妥的,耐心看完它基本就了解得差不多了。

将sring寫入buf執行個體,同時傳回寫入的位元組數。

參數如下:

string:寫入的字元串。

offset:從buf的第幾位開始寫入,預設是0。

length:寫入多少個位元組,預設是 buf.length - offset。

encoding:字元串的編碼,預設是utf8。

看個簡單例子

用<code>value</code>填充buf,常用于初始化buf。參數說明如下:

value:用來填充的内容,可以是buffer、string或integer。

offset:從第幾位開始填充,預設是0。

end:停止填充的位置,預設是 buf.length。

encoding:如果<code>value</code>是string,那麼為<code>value</code>的編碼,預設是utf8。

例子:

把buf解碼成字元串,用法比較直覺,看例子

用于對<code>buf</code>進行<code>for...of</code>周遊,直接看例子。

用于截取buf,并傳回一個新的buffer執行個體。需要注意的是,這裡傳回的buffer執行個體,指向的仍然是buf的記憶體位址,是以對新buffer執行個體的修改,也會影響到buf。

建立、拷貝、截取、轉換、查找

buffer、arraybuffer、dataview、typedarray

buffer vs 編碼

buffer.from()、buffer.alloc()、buffer.alocunsafe()

buffer vs typedarray

關于buffer記憶體空間的動态配置設定

instances of the buffer class are similar to arrays of integers but correspond to fixed-sized, raw memory allocations outside the v8 heap. the size of the buffer is established when it is created and cannot be resized.

unicode對照表

<a href="https://unicode-table.com/cn/#control-character">https://unicode-table.com/cn/#control-character</a>

字元編碼筆記:ascii,unicode和utf-8

<a href="http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html">http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html</a>

繼續閱讀