国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Node閑談之Buffer

Godtoy / 750人閱讀

摘要:閑談系列不涉及具體的講解,只會勾勾畫畫一些自己認為比較重要的特性。我們一般認為用兩個字節位表示,并且完全囊括了字符集。將其轉換成進制就是只是表示它們是碼。三的讀取和寫入相關重要的只有能夠讀寫,才能夠顯示其存在的價值。

原文地址:http://www.cnblogs.com/DeanCh...

在剛接觸Nodejs的時候,有些概念總讓學前端的我感到困惑(雖然大學的時候也是在搞后端,世界上最好的語言,you know)。我可以很快理解File System,Path等帶有明顯功能的模塊,卻一下子不能理解Buffer這個玄而又玄的東西。因為,在前端的js實踐中,我很少去考慮什么編碼方式,字符集之類的東西。二進制的理解僅限于大學課堂而已。本文與其說是在探討Node的Buffer模塊,倒不如說是來探討下如何從字符集,編碼的角度來理解Buffer這個模塊設立的意義。Node閑談系列不涉及具體的API講解,只會勾勾畫畫一些自己認為比較重要的特性。

一、基本知識

正如我們學習編程的第一節課一樣,我們明白,計算機就是一個二進制生物。它只能理解1和0,或者說有和沒有。“太極生兩儀,兩儀生四象,四象生八卦”。我們在計算上看到的無論是任何東西,都是通過某種特殊的編碼方式,或者說是約定展現出來的。

我們很熟悉的ASCII碼就是這樣一種規范,和摩爾斯碼一樣,固定的值表示固定的含義。ASCII碼用1個字節8位來表示2^8=256種狀態。比如大寫字母A對應的是65,B對應66,是不是很簡單。ASCII碼并不是占滿了所有的256個位置,只用到了一半128位。在一個字節中,只占用后面7位,最前面一位統一標識為0。

但是我們很容易就發現,ASCII碼遠遠是不夠的,最起碼我們漢字就表示不了。后面考慮了許多其他解決方案,我們在此不多敘述,直接說最終解決方案——Unicode。Unicode想法很直接,就是想把全世界所有的字符都囊括進去。我們一般認為Unicode用兩個字節16位表示,并且完全囊括了ASCII字符集。比如漢字“好”在unicode里面二進制表示是 0101 1001 0111 1101。將其轉換成16進制就是U597D(U只是表示它們是unicode碼)。之所以我前面說是“一般認為”,是因為這種想法是不準確的。Unicode一個平面(plane)是兩個字節。我們經常談論的是它的一個基本平面,編碼是U+0000到U+FFFF,常見字符都在這個平面。Unicode還有16個輔助平面,碼點范圍是U+010000一直到U+10FFFF。一般而言,我們只需要把關注點放在基本平面就好,并且要習慣Unicode的表示方式。因為,這是畢竟在各種編碼方式間轉化的“硬通貨”。

我們常常談到的utf-8,utf-16這些是什么呢?這些都是具體的編碼方式,而Unicode是個字符集。以utf-8為例,它在unicode碼的基礎上,進行重新編碼,把一些本身不需要占滿2個字節的轉化為1個字節。比如ASCII里面的那些字符,在unicode里面,第一個字節全是0,簡直是空間的浪費,也會把漢字編碼城3個字節。你盡可以在控制臺試下Buffer.from("我","utf8")看下編碼后占的字節數。

javascript使用哪種編碼方式?

javascript采用Unicode字符集,但是只支持一種編碼方式。那就是USC-2。是不是沒有聽說過?你可以把它理解成utf-16。但它和utf-16到底是什么關系呢?

兩者的關系簡單說,就是UTF-16取代了UCS-2,或者說UCS-2整合進了UTF-16。所以,現在只有UTF-16,沒有UCS-2。

UCS-2只支持兩個字節,而在它后面才出來的UTF-16在UCS-2的基礎上,利用輔助平面可以支持4個字節。既然是UCS-2整合進UTF-16,那就存在有的字符UTF-16有,而UCS-2不存在的情況。出現這種情況怎么辦?大家可以參考下參考資料里面阮老師的講述。

二、Buffer的生成

相關重要的API

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

Buffer.allocUnsafe(size)

Buffer.allocUnsafeSlow(size)

Buffer.from(array)

buf.fill(value[, offset[, end]][, encoding])

在Buffer生成的過程中,最大的關注點就是內存的申請和分配。原先new Buffer()生成Buffer的方法已經不建議再次使用,它和Buffer.allocUnsafe()方法一樣,可能包含敏感數據。

為什么會包含敏感數據呢?在生成buffer的過程中,不是一步到位,要分為兩步走,1,申請內存空間,2,申請的內存空間進行填充。Buffer.allocUnsafe()方法只完成了第一步。不完成第二步的后果就是,申請的空間可能“殘留了”以前內存上的數據。畢竟一塊兒內存在計算機中總是申請了再釋放,釋放了再申請,難免就會導致一些數據沒有被及時清理干凈。當然,由于少了第二步操作,速度自然快了不少。

const a = Buffer.allocUnsafe(10);
console.log(a)
// 打印結果總是不一樣的,但我們發現每一位上很可能不是00,這些數據就屬于敏感數據。

可以使用buf.fill(0)進行后期的填充。但為了避免漏洞產生,應該避免使用Buffer.allocUnsafe()來分配內存。

Buffer.alloc()Buffer.allocUnsafe()安全的原因在于它在第二步會把所有的舊數據清除掉,填充成0。

const a = Buffer.alloc(10);
console.log(a)
// 打印結果每一位都是0。

看到這里,你是不是以為Buffer.alloc()Buffer.allocUnsafe()的區別僅限于有沒有填充數據?其實并不是的。真正與Buffer.alloc()差別在是否填充數據的是Buffer.allocUnsafeSlow()。原來,使用Buffer.allocUnsafe()分配內存需要借助共享內存池(shared internal memory pool)。而Buffer.alloc()Buffer.allocUnsafeSlow()是直接在內存空間上開辟相應大小的內存空間。

Buffer.allocUnsafe() (與之前的 new Buffer(size) 機制類似)是三者中分配內存速度最快的方式,它采用了共享內存池(shared internal memory pool)這一方式,通過預先分配一定大小的一段內存,從中再向 JavaScript 分配相應大小的片段,避免頻繁的向系統申請內存分配,來達到較高的效率。共享內存池的默認值 poolSize 為 8KB(可重新賦值),只有當需要分配的內存小于等于 poolSize 的一半時,Buffer.allocUnsafe() 才會從共享內存池從分配空間。

這里的知識點到為止,詳細的探討以后可以可以考慮專門寫一篇來說明,參考資料的內容也是相當不錯,建議閱讀。

三、Buffer的讀取和寫入

相關重要的API

buf.readInt8(offset[, noAssert])

buf.readDoubleBE(offset[, noAssert])

buf.readDoubleLE(offset[, noAssert])

buf.writeUInt8(value, offset[, noAssert])

buf.writeUInt16BE(value, offset[, noAssert])

buf.writeUInt16LE(value, offset[, noAssert])

...

buffer只有能夠讀寫,才能夠顯示其存在的價值。查看Buffer的文檔,Buffer的讀寫方法中有非常多以“BE”和“LE”結尾的方法。他們分別代表什么呢?

大字序和小字序

“BE”表示的是“big endian”大端字節序,而“LE”自然表示“little endian”小端字節序。字節序是干什么的呢?我們在描述一個字符的unicode碼的時候,習慣性地從左到右去寫。為什么不可以從右右往左寫呢?多個字節無論是讀取還是寫入,總要有一個順序,這就是“字節序”。大端序就是我們常看到的高位字節在前,低位字節在后,小端序恰好相反。

為什么要區分大端序和小端序呢?不能都統一從一個方向讀取,寫入么?

計算機電路先處理低位字節,效率比較高,因為計算都是從低位開始的。所以,計算機的內部處理都是小端字節序。
但是,人類還是習慣讀寫大端字節序。所以,除了計算機的內部處理,其他的場合幾乎都是大端字節序,比如網絡傳輸和文件儲存。

字節序的處理,就是一句話:"只有讀取的時候,才必須區分字節序,其他情況都不用考慮。"

好,下面我們舉個實際的例子。

var buf = Buffer.from([1,3,5,7]);
//

buf.readInt16BE(0)
//259    
從buf中讀取16位的整數,所以讀取的第一個字符對應的碼點是 01 03轉化成10進制就是1*16^2+3 = 259。
buf.readInt16LE(0)
//756
// 小字序從右往左讀取,第一個字符對應的碼點是 03 01 轉化成10進制就是3*16^2+1 = 756 

讀取和寫入是一個相反的過程,道理是一樣的。

//官方示例
const buf = Buffer.allocUnsafe(4);

buf.writeUInt8(0x3, 0);
buf.writeUInt8(0x4, 1);
buf.writeUInt8(0x23, 2);
buf.writeUInt8(0x42, 3);

// Prints: 
console.log(buf);

Buffer還有很多很有意思的方面需要進一步學習,待以后再進一步補充本文或者寫幾篇相關更為深入的文章。

未完待續。。。

參考資料

Unicode與JavaScript詳解

字符編碼筆記:ASCII,Unicode 和 UTF-8

Node.js 模塊之 Buffer

Node源碼解析 – buffer

理解字節序

Buffer/Stream與內存管理

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89576.html

相關文章

  • 閑談異步調用“扁平”化

    摘要:而的主線程中不允許操作網絡,更是將程序員們推向了異步的深淵。異步深淵產生的主要原因是回調,這在里尤其嚴重。為了逃離回調的深淵,大家開始想各種辦法來把回調扁平化。目前已經在等環境中得到支持,使用的不僅能大大簡化代碼,還能降低邏輯思路的復雜度。 哦,代碼……就把它們當成插圖吧 隨著 CPU 從單核變多核,軟件從注重功能到注重體驗,Web 從頁面跳轉方式到 Web2.0 的無刷新加載(AJA...

    Jaden 評論0 收藏0
  • DBASK問答集萃(2)

    摘要:新晉技術專家下面是墨天輪部分新晉的技術專家。大家可以點擊往期閱讀墨天輪技術專家邀請函了解詳情,申請成為我們的技術專家,加入專家團隊,與我們一起創建一個開放互助的數據庫技術社區。新關聯公眾號墨天輪是一個開放互助的數據庫技術社區。 引言 近期我們在DBASK小程序增加了數據庫 MongoDB、Redis、 Elasticsearch、DB2、Weblogic 等新的的專題欄目和一些新的技術...

    liuchengxu 評論0 收藏0
  • 閑談 Kubernetes 的主要特性和經驗分享

    摘要:主要介紹的主要特性和一些經驗。先從整體上看一下的一些理念和基本架構,然后從網絡資源管理存儲服務發現負載均衡高可用安全監控等方面向大家簡單介紹的這些主要特性。集群范圍內的監控主要由和如構建。 主要介紹 Kubernetes 的主要特性和一些經驗。先從整體上看一下Kubernetes的一些理念和基本架構, 然后從網絡、 資源管理、存儲、服務發現、負載均衡、高可用、rolling upgra...

    Guakin_Huang 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<