Node進(jìn)階 ---- Buffer

1. 什么是Buffer

  • 緩沖區(qū)Buffer是暫時(shí)存放輸入輸出數(shù)據(jù)的一段內(nèi)存烹困。
  • JS語(yǔ)言沒(méi)有二進(jìn)制數(shù)據(jù)類(lèi)型嘲更,而在處理TCP和文件流的時(shí)候上沐,必須要處理二進(jìn)制數(shù)據(jù)胯努。
  • NodeJS提供了一個(gè)Buffer對(duì)象來(lái)提供對(duì)二進(jìn)制數(shù)據(jù)的操作
  • 是一個(gè)表示固定內(nèi)存分配的全局對(duì)象纤勒,也就是說(shuō)要放到緩存區(qū)中的字節(jié)數(shù)需要提前確定
  • Buffer好比由一個(gè)8位字節(jié)元素組成的數(shù)組泛鸟,可以有效的在JavasScript中表示二進(jìn)制數(shù)據(jù)

2. 什么是字節(jié)

  • 字節(jié)(Byte)是計(jì)算機(jī)存儲(chǔ)時(shí)的一種計(jì)量單位,一個(gè)字節(jié)等于8位二進(jìn)制數(shù)
  • 一個(gè)位就代表一個(gè)0或1踊东,每8個(gè)位(bit)組成一個(gè)字節(jié)(Byte)
  • 字節(jié)是通過(guò)網(wǎng)絡(luò)傳輸信息的單位
  • 一個(gè)字節(jié)最大值十進(jìn)制數(shù)是255 2**8-1;

進(jìn)制

  • 0b 2進(jìn)制

  • 0x 16進(jìn)制

  • 0o 8進(jìn)制

  • 將任意進(jìn)制字符串轉(zhuǎn)換為十進(jìn)制

    • parseInt("11", 2); // 3 2進(jìn)制轉(zhuǎn)10進(jìn)制
    • parseInt("77", 8); // 63 8進(jìn)制轉(zhuǎn)10進(jìn)制
    • parseInt("e7", 16); //175 16進(jìn)制轉(zhuǎn)10進(jìn)制
  • 將10進(jìn)制轉(zhuǎn)換為其它進(jìn)制字符串

    • (3).toString(2)) // "11" 十進(jìn)制轉(zhuǎn)2進(jìn)制
    • (17).toString(16) // "11" 十進(jìn)制轉(zhuǎn)16進(jìn)制
    • (33).toString(32) // "11" 十提制轉(zhuǎn)32進(jìn)制

3. 定義buffer的三種方式

3.1 通過(guò)長(zhǎng)度定義buffer

// 創(chuàng)建一個(gè)長(zhǎng)度為 10北滥、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);
// 創(chuàng)建一個(gè)長(zhǎng)度為 10闸翅、且用 0x1 填充的 Buffer再芋。
const buf2 = Buffer.alloc(10, 1);
// 創(chuàng)建一個(gè)長(zhǎng)度為 10、且未初始化的 Buffer坚冀。
const buf3 = Buffer.allocUnsafe(10);

3.2 通過(guò)數(shù)組定義buffer

// 創(chuàng)建一個(gè)包含 [0x1, 0x2, 0x3] 的 Buffer济赎。
const buf4 = Buffer.from([1, 2, 3]);

正常情況下為0-255之間;

3.3 字符串創(chuàng)建

const buf5 = Buffer.from('張熙沐楓');

4.buffer常用方法

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

手動(dòng)初始化,擦干凈桌子,將buffer內(nèi)容清0

buffer.fill(0);

4.2 write方法

buf.write(string[, offset[, length]][, encoding])

buffer.write('沐',0,3,'utf8');
buffer.write('楓',3,3,'utf8'); //沐楓

4.3 writeInt8

var buf = new Buffer(4);
buf.writeInt8(0,0);
buf.writeInt8(16,1);
buf.writeInt8(32,2);
buf.writeInt8(48,3);//16*3*/
console.log(buf);
console.log(buf.readInt8(0));
console.log(buf.readInt8(1));
console.log(buf.readInt8(2));
console.log(buf.readInt8(3));

4.3.1 Little-Endian&Big-Endian

不同的CPU有不同的字節(jié)序類(lèi)型,這些字節(jié)序是指整數(shù)在內(nèi)存中保存的順序。

  • Big-endian:將高序字節(jié)存儲(chǔ)在起始地址(高位編址)

  • Little-endian:將低序字節(jié)存儲(chǔ)在起始地址(低位編址)

    let buf3 = new Buffer(4);
    buf3.writeInt16BE(2**8,0);
    console.log(buf3);//<Buffer 01 00 00 00>
    console.log(buf3.readInt16BE(0));
    
    buf3.writeInt16LE(2**8,2);
    console.log(buf3);//<Buffer 01 00 00 01>
    console.log(buf3.readInt16LE(2));
    

4.3 toString方法

buf.toString([encoding[, start[, end]]])

buffer.toString('utf8',3,6)

4.4 slice方法 [#](#t134.4 slice方法)

buf.slice([start[, end]])

let newBuf = buffer.slice(0,4);

4.4.1 截取亂碼問(wèn)題

let {StringDecoder}  = require('string_decoder');
let sd = new StringDecoder();
let buffer = new Buffer('沐楓');
console.log(sd.write(buffer.slice(0,4)));
console.log(sd.write(buffer.slice(4)));

4.5 copy方法

復(fù)制Buffer 把多個(gè)buffer拷貝到一個(gè)大buffer上

buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])
let buf5 = Buffer.from('張熙沐楓');
let buf6 = Buffer.alloc(6);
buf5.copy(buf6,0,0,4);
buf5.copy(buf6,3,3,6);
//buf6=沐楓
Buffer.prototype.copy2 = function(targetBuffer,targetStart,sourceStart,sourceEnd){
    for(let i=sourceStart;i<sourceEnd;i++){
        target[targetStart+i] = this[i];
    }
}

4.6 concat方法

Buffer.concat(list[, totalLength])
let buf1 = Buffer.from('沐');
let buf2 = Buffer.from('楓');
let buf3 = Buffer.concat([buf1,buf2],3);
console.log(buf3.toString());
Buffer.concat2 = function (list = [], total = list.reduce((len, item) => len + item.length, 0)) {
    if (list.length == 1)
        return list[0];
    let result = Buffer.alloc(total);
    let pos = 0;
    for (let bf of list) {
        for (let b of bf) {
            if (pos < total)
                result[pos++] = b;
            else
                return result;
        }
    }
    return result;
}
Buffer.myConcat = function(list,totalLength=list.reduce((len,item)=>len+item.length,0)){
  if(list.length==0)
    return list[0];
  let newBuffer = Buffer.alloc(totalLength);
  let offset = 0;
  for(let i=0;i<list.length;i++){
    if(offset+list[i].length>totalLength){
      list[i].copy(newBuffer,offset,0,totalLength-offset);
      break;
    }else{
      list[i].copy(newBuffer,offset,0,list[i].length);
      offset+=list[i].length;
    }
  }
  return newBuffer;
}

4.7 isBuffer

判斷是否是buffer

Buffer.isBuffer

4.8 length

獲取字節(jié)長(zhǎng)度(顯示是字符串所代表buffer的長(zhǎng)度)

Buffer.byteLength("沐楓");
buffer.length;

6. base64

  • Base64是網(wǎng)絡(luò)上最常見(jiàn)的用于傳輸8Bit字節(jié)碼的編碼方式之一司训,Base64就是一種基于64個(gè)可打印字符來(lái)表示二進(jìn)制數(shù)據(jù)的方法构捡。

  • Base64要求把每三個(gè)8Bit的字節(jié)轉(zhuǎn)換為四個(gè)6Bit的字節(jié)(3_8 = 4_6 = 24),然后把6Bit再添兩位高位0壳猜,組成四個(gè)8Bit的字節(jié)勾徽,也就是說(shuō),轉(zhuǎn)換后的字符串理論上將要比原來(lái)的長(zhǎng)1/3

    const CHARTS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    function transfer(str){
      let buf = Buffer.from(str);
      let result = '';
      for(let b of buf){
          result += b.toString(2);
      }
        return result.match(/(\d{6})/g).map(val=>parseInt(val,2)).map(val=>CHARTS[val]).join('');
    }
    let r = transfer('珠');//54+g
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末统扳,一起剝皮案震驚了整個(gè)濱河市喘帚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咒钟,老刑警劉巖吹由,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異朱嘴,居然都是意外死亡倾鲫,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)萍嬉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)级乍,“玉大人,你說(shuō)我怎么就攤上這事帚湘∶等伲” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵大诸,是天一觀的道長(zhǎng)捅厂。 經(jīng)常有香客問(wèn)我,道長(zhǎng)资柔,這世上最難降的妖魔是什么焙贷? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮贿堰,結(jié)果婚禮上辙芍,老公的妹妹穿的比我還像新娘。我一直安慰自己羹与,他們只是感情好故硅,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著纵搁,像睡著了一般吃衅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上腾誉,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天徘层,我揣著相機(jī)與錄音峻呕,去河邊找鬼。 笑死趣效,一個(gè)胖子當(dāng)著我的面吹牛瘦癌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播跷敬,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼讯私,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了干花?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤楞黄,失蹤者是張志新(化名)和其女友劉穎池凄,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鬼廓,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肿仑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碎税。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尤慰。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖雷蹂,靈堂內(nèi)的尸體忽然破棺而出伟端,到底是詐尸還是另有隱情,我是刑警寧澤匪煌,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布责蝠,位于F島的核電站,受9級(jí)特大地震影響萎庭,放射性物質(zhì)發(fā)生泄漏霜医。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一驳规、第九天 我趴在偏房一處隱蔽的房頂上張望肴敛。 院中可真熱鬧,春花似錦吗购、人聲如沸医男。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)昨登。三九已至,卻和暖如春贯底,著一層夾襖步出監(jiān)牢的瞬間丰辣,已是汗流浹背撒强。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留笙什,地道東北人飘哨。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像琐凭,于是被迫代替她去往敵國(guó)和親芽隆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Node.js Buffer(緩沖區(qū)) JavaScript 語(yǔ)言自身只有字符串?dāng)?shù)據(jù)類(lèi)型统屈,沒(méi)有二進(jìn)制數(shù)據(jù)類(lèi)型胚吁。但在...
    FTOLsXD閱讀 502評(píng)論 0 2
  • Buffer是node的核心模塊,開(kāi)發(fā)者可以利用它來(lái)處理二進(jìn)制數(shù)據(jù)愁憔,比如文件流的讀寫(xiě)腕扶、網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)的處理等。 Bu...
    自度君閱讀 499評(píng)論 0 1
  • 剛跨進(jìn)高中的大門(mén),便有兒時(shí)玩伴告訴我膜宋,他有個(gè)很帥的初中同學(xué)在我班上窿侈,但是讓我千萬(wàn)不要喜歡他。我對(duì)此嗤之以鼻秋茫,我是什...
    56fdf6a7f26e閱讀 355評(píng)論 0 0
  • 人艱不拆肛著,我不說(shuō)話乘瓤,就寫(xiě)寫(xiě) 一個(gè)月前,編制考試慘敗策泣,出不了國(guó)衙傀,剛畢業(yè)沒(méi)經(jīng)驗(yàn),沒(méi)有合適的工作崗位萨咕,被喜歡的人...
    蔥白頭閱讀 976評(píng)論 2 9
  • 夕陽(yáng)的傳遞方式 無(wú)非是 從高一些的樹(shù)慢慢 滾落到矮一些的樹(shù) 然后再被更矮的灌木接過(guò)去 就這樣下樓梯般 一步一步 沒(méi)...
    伏櫪齋閱讀 156評(píng)論 0 1