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 > length:傳回長度為totallength的buffer執行個體,超出長度的部分填充0。
totallength < 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>