深刻基礎(四)Buffer,轉碼

Bufferjavascript

    前面說起到一些關於buffer類的問題,當時不是很明確 那麼就次機會順便深刻探討一下這個東西到底幹嗎的出如今何時,如何使用.昨天跟朋友聊天他說我每一篇博文內容太長太長了 雖然很精細,可是的確深刻的有點多了,so 這篇開始儘可能多分幾篇共同討論,減小單一文章內容過多的問題哈.  想起個事兒來這,這兩篇博文其實都是在深挖原生模塊fs,原生若是操做文件的,細心的孩砸都會發現的,對於fs模塊學習還有兩章,我準備這兩張完事兒以後開始學習http模塊 目前項目中有用到部分http模塊的功能,好了不廢話了繼續往下看.php

      上篇文章圍繞數據文件操做探討了一下node裏面如何操做文件的,可是javascript中只有字符串類型,並不支持二進制(文件操做都是二進制類型的,這也就解決了讀取文件時候爲啥不區分文件類別的問題,由於無論啥文件txt,php等等內容都會當作二進制數據取處理,我的理解啊並不表明官方解釋),搶到的node工程師們確定不能容忍這麼low的問題,所以buffer誕生了,buffer說是一個類,更準確的說是一個緩存區域!它在內存中的做用就是單獨存放二進制說的區域.在nodejs中buffer是隨着node一同發佈的核心庫,他是存在於V8堆內存以外的一塊原始內存中.而這個內存大小在官方文檔中也有說明:html

      目前,V8引擎有一個默認的32位系統512MB內存的限制,在64位系統1.4gb。極限可提升設置- max_old_space_size到最大~ 1024(~ 1 GB)(32位)和4096(~ ~ 4GB)(64位),但建議你把你的單過程分紅幾個工人若是你命中內存限制。java

      可是Buffer是若是回收的如何設定有效時間期限的真的很難找到相關文章,不過確實會被GC回收,相關文章我就再也不這裏貼出來了關於這方面的文章真的太少了..彷佛沒人去挖這個仍是不值得去挖呢?node

      buffer類的建立相似於建立數組 :redis

              var b=new buffer(10); //建立一個10字節的實例npm

              var b=new buffer([1,2,3])//固然裏面也能夠是數組數組

              var b=new buffer("嘿嘿嘿","utf-8")//這個也能夠有 並且還設定了編碼方式緩存

     buffer.write數據結構

     buf.write(string,[offset],[length],[encoding]),寫入buffer的參數,string 須要寫入的字符串,offset 緩存區開始的索引值,length 寫入長度(固然若是緩存區滿了就只能寫入部分啦),encoding 編碼方式 默認UTF-8

     一個小李子:

buf = new Buffer(256);
len = buf.write("www.w3cschool.cn");

console.log("寫入字節數 : "+  len);

  這個緩存方式有點點像redis,可是它並無有效期啊什麼什麼的,並且格式也是截然不同,給個人感受這個寫入緩存區的就是一個txt文本...啥都是一行裏面一直寫下去可是如何找到指定的內容呢?

     bufffer.toString

     是否是感受很low比...別忘了 人家也是有參數的buffer.toString(encoding,start,end),你寫在什麼位置了直接取唄來來上例子看一下瞬間明白了:  

buf = new Buffer(26);
for (var i = 0 ; i < 26 ; i++) {
  buf[i] = i + 97;
}

console.log( buf.toString('ascii'));       // 輸出: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5));   // 輸出: abcde
console.log( buf.toString('utf8',0,5));    // 輸出: abcde
console.log( buf.toString(undefined,0,5)); // 使用 'utf8' 編碼, 並輸出: abcde

  好了額,還有不少灰常灰常簡單的方法,例如: 比較compare,合併concat,複製copy,剪切slice 我就不一一介紹了,看看文檔簡直不要再簡單了...http://www.w3cschool.cn/nodejs/x1u41ith.html

     這裏我要說一下它的不少不少轉換方法,前面也說到了實際上buffer緩存區域是有大小的並且是有回收機制的(雖然不清楚)大小確定是有限制的能省點就省點先介紹一下轉換方法:     

     閱讀Buffer的API文檔時,咱們會發現更多的是readXXX()writeXXX()開頭的API,具體以下:

  • buf.readUIntLE(offset, byteLength[, noAssert])
  • buf.readUIntBE(offset, byteLength[, noAssert])
  • buf.readIntLE(offset, byteLength[, noAssert])
  • buf.readIntBE(offset, byteLength[, noAssert])
  • buf.readUInt8(offset[, noAssert])
  • buf.readUInt16LE(offset[, noAssert])
  • buf.readUInt16BE(offset[, noAssert])
  • buf.readUInt32LE(offset[, noAssert])
  • buf.readUInt32BE(offset[, noAssert])
  • buf.readInt8(offset[, noAssert])
  • buf.readInt16LE(offset[, noAssert])
  • buf.readInt16BE(offset[, noAssert])
  • buf.readInt32LE(offset[, noAssert])
  • buf.readInt32BE(offset[, noAssert])
  • buf.readFloatLE(offset[, noAssert])
  • buf.readFloatBE(offset[, noAssert])
  • buf.readDoubleLE(offset[, noAssert])
  • buf.readDoubleBE(offset[, noAssert])
  • buf.write(string[, offset][, length][, encoding])
  • buf.writeUIntLE(value, offset, byteLength[, noAssert])
  • buf.writeUIntBE(value, offset, byteLength[, noAssert])
  • buf.writeIntLE(value, offset, byteLength[, noAssert])
  • buf.writeIntBE(value, offset, byteLength[, noAssert])
  • buf.writeUInt8(value, offset[, noAssert])
  • buf.writeUInt16LE(value, offset[, noAssert])
  • buf.writeUInt16BE(value, offset[, noAssert])
  • buf.writeUInt32LE(value, offset[, noAssert])
  • buf.writeUInt32BE(value, offset[, noAssert])
  • buf.writeInt8(value, offset[, noAssert])
  • buf.writeInt16LE(value, offset[, noAssert])
  • buf.writeInt16BE(value, offset[, noAssert])
  • buf.writeInt32LE(value, offset[, noAssert])
  • buf.writeInt32BE(value, offset[, noAssert])
  • buf.writeFloatLE(value, offset[, noAssert])
  • buf.writeFloatBE(value, offset[, noAssert])
  • buf.writeDoubleLE(value, offset[, noAssert])
  • buf.writeDoubleBE(value, offset[, noAssert])

    這些API爲在Node.js中操做數據提供了極大的便利。假設咱們要將一個整形數值存儲到文件中,好比當前時間戳爲1447656645380,若是將其看成一個字符串存儲時,須要佔用11字節的空間,而將其轉換爲二進制存儲時僅需6字節空間便可: 

var buf = new Buffer(6);

buf.writeUIntBE(1447656645380, 0, 6);
// <Buffer 01 51 0f 0f 63 04>

buf.readUIntBE(0, 6);
// 1447656645380

  這段來自另一位大神一年前的博客了而且根據取出數據結構被混亂特地寫了一個模塊去解決這個問題lei-proto 有時間膜拜一下,傳送門-->http://cnodejs.org/topic/56499568d28aa64101600fdc

編碼轉換

   這裏主要是介紹一下中文轉換我接觸的兩個第三方庫,不少人都在用與其一直用新東西探索未知區域我更願意相信舊的,畢竟千萬人都使用過..不廢話了

     前面常常用到toString()這個方法而node自己對中文以及其餘多字節編碼支持並很差,須要第三方庫來協調一下,這裏主要介紹一下經常使用的iconv-lite和encoding

     iconv-lite

     首先先來了解一下iconv, iconv-lite,encoding:

     iconv:是在類Unix系統中一種標準字符集轉換接口,用於在不一樣字符集編碼之間進行轉換,最先出如今HP-UX系統中,闡釋了node-iconv的起源.

     iconv-lite:是iconv的純js實現,支持的編碼包括node.js原生編碼:utf8, ucs2, ascii, binary, base64;同時支持普遍使用的單字節編碼:Windows 125x family, ISO-8859 family, IBM/DOS codepages, Macintosh family, KOI8 family, latin1, us-ascii;多字節編碼:gbk, gb2313, Big5, cp950。官方宣稱比node-iconv更快。
 
     encoding:是對node-iconv和iconv-lite的再次封裝,encoding首先調用node-iconv,若是node-iconv沒法解析,則調用iconv-lite做爲替代方案.至關於iconv-lite的包裝版.
     
     這兩個第三方庫 安裝都同樣sup簡單 npm install iconv-lite  或者 npm install encoding
     
     使用方法我考了別人兩段代碼基本上看看就知道了沒啥特殊的,都是 替代了原有的toString()方法,encoding稍微說一下,先是iconv-lite
     
var iconv = require('iconv-lite');
 
// Convert from an encoded buffer to js string.
str = iconv.decode(buf, 'win1251');
 
// Convert from js string to an encoded buffer.
buf = iconv.encode("Sample input string", 'win1251');
 
// Check if encoding is supported
iconv.encodingExists("us-ascii")

  encoding 須要繞個小丸子,encoding模塊就一個方法convert(),使用方法爲:encoding.convert(text, toCharset, fromCharset)。 

             text: 須要轉換的對象,能夠爲Buffer或者String對象。
             toCharset: 轉換後的編碼。
             fromCharset: 轉換前的編碼,缺省爲uft8。
            轉換後的輸入結果爲Buffer對象
      
var encoding = require('encoding');
 
var result = encoding.convert("ÕÄÖÜ", "Latin_1");
console.log(result); //<Buffer d5 c4 d6 dc>
相關文章
相關標籤/搜索