nodeJS之二進制buffer對象

前面的話

  在ES6引入TypedArray以前,JavaScript語言沒有讀取或操做二進制數據流的機制。Buffer類被引入做爲Nodejs的API的一部分,使其能夠在TCP流和文件系統操做等場景中處理二進制數據流。如今TypedArray已經被添加進ES6中,Buffer類以一種更優與更適合Node.js用例的方式實現了Uint8Array。本文將詳細介紹buffer對象html

 

概述

  因爲應用場景不一樣,在Node中,應用須要處理網絡協議、操做數據庫、處理圖片、接收上傳文件等,在網絡流和文件的操做中,還要處理大量二進制數據,JavaScript自有的字符串遠遠不能知足這些需求,因而Buffer對象應運而生node

  Buffer是一個典型的JavaScript與C++結合的模塊,它將性能相關部分用C++實現,將非性能相關的部分用JavaScript實現。Buffer類的實例相似於整數數組,除了其是大小固定的、且在V8堆外分配物理內存。Buffer的大小在其建立時就已肯定,且不能調整大小數據庫

  因爲Buffer太過常見,Node在進程啓動時就已經加載了它,並將其放在全局對象(global)上。因此在使用Buffer時,無須經過require()便可直接使用json

/*
{ [Function: Buffer]
  poolSize: 8192,
  from: [Function],
  alloc: [Function],
  allocUnsafe: [Function],
  allocUnsafeSlow: [Function],
  isBuffer: [Function: isBuffer],
  compare: [Function: compare],
  isEncoding: [Function],
  concat: [Function],
  byteLength: [Function: byteLength] }
 */
console.log(Buffer);

 

建立

  在 Node.js v6以前的版本中,Buffer實例是經過Buffer構造函數建立的,它根據提供的參數返回不一樣的 Buffer,而新版本的nodejs則提供了對應的方法數組

  一、new Buffer(size)。傳一個數值做爲第一個參數給Buffer()(如new Buffer(10)),則分配一個指定大小的新建的Buffer對象安全

  分配給這種Buffer實例的內存是未初始化的(沒有用0填充)。雖然這樣的設計使得內存的分配很是快,但已分配的內存段可能包含潛在的敏感舊數據網絡

  這種Buffer實例必須手動地被初始化,可使用buf.fill(0)或寫滿這個Buffer。雖然這種行爲是爲了提升性能而有意爲之的,但開發經驗代表,建立一個快速但未初始化的Buffer與建立一個慢點但更安全的Buffer之間須要有更明確的區分函數

var buf = new Buffer(5);
console.log(buf);//<Buffer e0 f7 1d 01 00>
buf.fill(0);
console.log(buf);//<Buffer 00 00 00 00 00>

  [注意]當咱們爲一個Buffer對象分配空間大小後,其長度就是固定的,不能更改性能

var buf = new Buffer(5);
console.log(buf);//<Buffer b8 36 70 01 02>
buf[0] = 1;
console.log(buf);//<Buffer 01 36 70 01 02>
buf[10] = 1;
console.log(buf);//<Buffer 01 79 43 6f 6e>

  【Buffer.allocUnsafe(size)】ui

   在新版本中,由Buffer.allocUnsafe(size)方法替代,來分配一個大小爲 size 字節的新建的沒有用0填充的Buffer。可使用buf.fill(0)初始化Buffer實例爲0

var buf = Buffer.allocUnsafe(10);
console.log(buf);//<Buffer 75 63 74 42 79 4c 65 6e 67 74>
buf.fill(0);
console.log(buf);//<Buffer 00 00 00 00 00 00 00 00 00 00>

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

  在新版本中,使用Buffer.alloc(size)方法能夠生成一個安全的buffer對象,參數size <Integer> 新建的 Buffer 指望的長度;fill <String> | <Buffer> | <Integer> 用來預填充新建的 Buffer 的值。 默認: 0;encoding <String> 若是 fill 是字符串,則該值是它的字符編碼。 默認: 'utf8'

  分配一個大小爲 size 字節的新建的 Buffer 。 若是 fill 爲 undefined ,則該 Buffer 會用 0 填充

var buf = Buffer.alloc(5);
console.log(buf);//<Buffer 00 00 00 00 00>

  二、new Buffer(array或buffer)。傳一個數組或Buffer做爲第一個參數,則將所傳對象的數據拷貝到Buffer 

var buf1 = new Buffer([1, 2, 3, 4, 5]);
console.log(buf1);//<Buffer 01 02 03 04 05>
var buf2 = new Buffer(buf1);
console.log(buf2);//<Buffer 01 02 03 04 05>

  【Buffer.from(array或buffer)】

   在新版本中,由Buffer.from(array或buffer)方法替代

var buf1 = Buffer.from([1, 2, 3, 4, 5]);
console.log(buf1);//<Buffer 01 02 03 04 05>
var buf2 = Buffer.from(buf1);
console.log(buf2);//<Buffer 01 02 03 04 05>

  三、new Buffer(string[, encoding])。第一個參數是字符串,第二個參數是編碼方式,默認是'utf-8'

var buf1 = new Buffer('this is a tést');
console.log(buf1.toString());//this is a tést
console.log(buf1.toString('ascii'));//this is a tC)st
var buf2 = new Buffer('7468697320697320612074c3a97374', 'hex');
console.log(buf2.toString());//this is a tést

  Node.js 目前支持的字符編碼包括:

'ascii' - 僅支持 7 位 ASCII 數據。若是設置去掉高位的話,這種編碼是很是快的。
'utf8' - 多字節編碼的 Unicode 字符。許多網頁和其餘文檔格式都使用 UTF-8'utf16le' - 2 或 4 個字節,小字節序編碼的 Unicode 字符。支持代理對(U+10000 至 U+10FFFF)。
'ucs2' - 'utf16le' 的別名。
'base64' - Base64 編碼。當從字符串建立 Buffer 時,這種編碼可接受「URL 與文件名安全字母表」。
'latin1' - 一種把 Buffer 編碼成一字節編碼的字符串的方式。
'binary' - 'latin1' 的別名。
'hex' - 將每一個字節編碼爲兩個十六進制字符。

  【Buffer.from(string[, encoding])】

  在新版本中,由Buffer.from(string[, encoding]方法替代

var buf1 = Buffer.from('this is a tést');
console.log(buf1.toString());//this is a tést
console.log(buf1.toString('ascii'));//this is a tC)st
var buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');
console.log(buf2.toString());//this is a tést

  四、new Buffer(arrayBuffer[, byteOffset [, length]])。參數arrayBuffer <ArrayBuffer> 一個 ArrayBuffer,或一個 TypedArray 的 .buffer 屬性;byteOffset <Integer> 開始拷貝的索引。默認爲 0;length <Integer> 拷貝的字節數。默認爲 arrayBuffer.length - byteOffset

var arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
var buf = new Buffer(arr.buffer);
console.log(buf);//<Buffer 88 13 a0 0f>
arr[1] = 6000;
console.log(buf);//<Buffer 88 13 70 17>

  【Buffer.from(arrayBuffer[, byteOffset [, length]])】

  在新版本中,由Buffer.from(arrayBuffer[, byteOffset [, length]])方法替代

var arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
var buf = Buffer.from(arr.buffer);
console.log(buf);//<Buffer 88 13 a0 0f>
arr[1] = 6000;
console.log(buf);//<Buffer 88 13 70 17>

 

類數組

  Buffer對象相似於數組,它的元素爲16進制的兩位數,即0到255的數值

console.log(Buffer.from('test'));//<Buffer 74 65 73 74>

【長度】

  不一樣編碼的字符串佔用的元素個數各不相同,中文字在UTF-8編碼下佔用3個元素,字母和半角標點符號佔用1個元素

var buf = Buffer.from('match');
console.log(buf.length);//5
var buf = Buffer.from('火柴');
console.log(buf.length);//6

【下標】

  Buffer受Array類型的影響很大,能夠訪問length屬性獲得長度,也能夠經過下標訪問元素

var buf = Buffer.alloc(10); 
console.log(buf.length); // => 10

  上述代碼分配了一個長10字節的Buffer對象。咱們能夠經過下標對它進行賦值

buf[0] = 100;
console.log(buf[0]); // => 100

  要注意的是,給元素的賦值若是小於0,就將該值逐次加256,直到獲得一個0到255之間的整數。若是獲得的數值大於255,就逐次減256,直到獲得0~255區間內的數值。若是是小數,捨棄小數部分,只保留整數部分

buf[0] = -100;
console.log(buf[0]); // 156
buf[1] = 300;
console.log(buf[1]); // 44
buf[2] = 3.1415;
console.log(buf[2]); // 3

【fromcharcode】

  一般地,建立的buffer對象的內容是其uft-8字符編碼

var buf = Buffer.from('match'); 
console.log(buf); //<Buffer 6d 61 74 63 68>

  若是要訪問其對應的字符,則須要使用字符串的fromCharCode()方法

console.log(String.fromCharCode(buf[0]));//'m'

 

內存分配

  Buffer對象的內存分配不是在V8的堆內存中,而是在Node的C++層面實現內存的申請的。由於處理大量的字節數據不能採用須要一點內存就向操做系統申請一點內存的方式,這可能形成大量的內存申請的系統調用,對操做系統有必定壓力。爲此Node在內存的使用上應用的是在C++層面申請內存、在JavaScript中分配內存的策略

  爲了高效地使用申請來的內存,Node採用了slab分配機制。slab是一種動態內存管理機制,最先誕生於SunOS操做系統(Solaris)中,目前在一些*nix操做系統中有普遍的應用,如FreeBSD和Linux。簡單而言,slab就是一塊申請好的固定大小的內存區域。slab具備以下3種狀態:full:徹底分配狀態;partial:部分分配狀態;empty:沒有被分配狀態

  當咱們須要一個Buffer對象,能夠經過如下方式分配指定大小的Buffer對象:

new Buffer(size);//
Buffer.alloc(size);//

【poolSize】

  poolSize屬性是用於決定預分配的、內部 Buffer 實例池的大小的字節數。默認地,Node以8KB爲界限來區分Buffer是大對象仍是小對象:

Buffer.poolSize = 8 * 1024;

  這個8KB的值也就是每一個slab的大小值,在JavaScript層面,以它做爲單位單元進行內存的分配

  一、分配小Buffer對象

  若是指定Buffer的大小少於8KB,Node會按照小對象的方式進行分配。Buffer的分配過程當中主要使用一個局部變量pool做爲中間處理對象,處於分配狀態的slab單元都指向它。如下是分配一個全新的slab單元的操做,它會將新申請的SlowBuffer對象指向它:

var pool;
function allocPool() {
    pool = new SlowBuffer(Buffer.poolSize);
    pool.used = 0;
}

  構造小Buffer對象時的代碼以下:

new Buffer(1024);//
Buffer.alloc(1024);//

  此次構造將會去檢查pool對象,若是pool沒有被建立,將會建立一個新的slab單元指向它:

if (!pool || pool.length - pool.used < this.length) allocPool();

  同時當前Buffer對象的parent屬性指向該slab,並記錄下是從這個slab的哪一個位置(offset)開始使用的,slab對象自身也記錄被使用了多少字節,代碼以下:

this.parent = pool; 
this.offset = pool.used; 
pool.used += this.length;
if (pool.used & 7) pool.used = (pool.used + 8) & ~7;

  這時候的slab狀態爲partial。當再次建立一個Buffer對象時,構造過程當中將會判斷這個slab的剩餘空間是否足夠。若是足夠,使用剩餘空間,並更新slab的分配狀態。下面的代碼建立了一個新的Buffer對象,它會引發一次slab分配:

new Buffer(3000);//
Buffer.alloc(3000);//

  若是slab剩餘的空間不夠,將會構造新的slab,原slab中剩餘的空間會形成浪費。例如,第一次構造1字節的Buffer對象,第二次構造8192字節的Buffer對象,因爲第二次分配時slab中的空間不夠,因此建立並使用新的slab,第一個slab的8KB將會被第一個1字節的Buffer對象獨佔。下面的代碼一共使用了兩個slab單元:

new Buffer(1);//
Buffer.alloc(1);//
new Buffer(8192);//
Buffer.alloc(8192);//

  要注意的是,因爲同一個slab可能分配給多個Buffer對象使用,只有這些小Buffer對象在做用域釋放並均可以回收時,slab的8KB空間纔會被回收。儘管建立了1個字節的Buffer對象,可是若是不釋放它,實際多是8KB的內存沒有釋放

  二、分配大Buffer對象

  若是須要超過8KB的Buffer對象,將會直接分配一個SlowBuffer對象做爲slab單元,這個slab單元將會被這個大Buffer對象獨佔

// Big buffer, just alloc one
this.parent = new SlowBuffer(this.length); 
this.offset = 0;

  這裏的SlowBuffer類是在C++中定義的,雖然引用buffer模塊能夠訪問到它,可是不推薦直接操做它,而是用Buffer替代

  上面提到的Buffer對象都是JavaScript層面的,可以被V8的垃圾回收標記回收。可是其內部的parent屬性指向的SlowBuffer對象卻來自於Node自身C++中的定義,是C++層面上的Buffer對象,所用內存不在V8的堆中

  綜上,真正的內存是在Node的C++層面提供的,JavaScript層面只是使用它。當進行小而頻繁的Buffer操做時,採用slab的機制進行預先申請和過後分配,使得JavaScript到操做系統之間沒必要有過多的內存申請方面的系統調用。對於大塊的Buffer而言,則直接使用C++層面提供的內存,而無需細膩的分配操做

 

轉換

  Buffer對象能夠與字符串之間相互轉換。目前支持的字符串編碼類型有以下幾種:ASCII、UTF-八、UTF-16LE/UCS-二、Base6四、Binary、Hex

【write()】

  一個Buffer對象能夠存儲不一樣編碼類型的字符串轉碼的值,調用write()方法能夠實現該目的

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

  string <String> 要寫入 buf 的字符串

  offset <Integer> 開始寫入 string 的位置。默認: 0

  length <Integer> 要寫入的字節數。默認: buf.length - offset

  encoding <String> string 的字符編碼。默認: 'utf8';返回: <Integer> 寫入的字節數

  根據 encoding 的字符編碼寫入 string 到 buf 中的 offset 位置。 length 參數是寫入的字節數。 若是 buf 沒有足夠的空間保存整個字符串,則只會寫入 string 的一部分。 只部分解碼的字符不會被寫入

var buf = Buffer.alloc(5); 
console.log(buf); //<Buffer 00 00 00 00 00>
var len = buf.write('test',1,3);
console.log(buf);//<Buffer 00 74 65 73 00>
console.log(len);/3

  因爲能夠不斷寫入內容到Buffer對象中,而且每次寫入能夠指定編碼,因此Buffer對象中能夠存在多種編碼轉化後的內容。須要當心的是,每種編碼所用的字節長度不一樣,將Buffer反轉回字符串時須要謹慎處理

【toString()】

  實現Buffer向字符串的轉換也十分簡單,Buffer對象的toString()能夠將Buffer對象轉換爲字符串

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

  encoding - 使用的編碼。默認爲 'utf8'

  start - 指定開始讀取的索引位置,默認爲 0

  end - 結束位置,默認爲緩衝區的末尾

  返回 - 解碼緩衝區數據並使用指定的編碼返回字符串

var buf =Buffer.alloc(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));//abcde

【toJSON()】

  將 Node Buffer 轉換爲 JSON 對象

buf.toJSON()

  返回 buf 的 JSON 格式

var buf = Buffer.from('test');
var json = buf.toJSON(buf);
console.log(json);//{ type: 'Buffer', data: [ 116, 101, 115, 116 ] }

【isEncoding()】

  目前比較遺憾的是,Node的Buffer對象支持的編碼類型有限,只有少數的幾種編碼類型能夠在字符串和Buffer之間轉換。爲此,Buffer提供了一個isEncoding()函數來判斷編碼是否支持轉換

Buffer.isEncoding(encoding)

  將編碼類型做爲參數傳入上面的函數,若是支持轉換返回值爲true,不然爲false。很遺憾的是,在中國經常使用的GBK、GB2312和BIG-5編碼都不在支持的行列中

console.log(Buffer.isEncoding('utf8'));//true
console.log(Buffer.isEncoding('gbk'));//false

 

類方法

【Buffer.byteLength(string[, encoding])】

  Buffer.byteLength()方法返回一個字符串的實際字節長度。 這與 String.prototype.length 不一樣,由於那返回字符串的字符數

  string <String> | <Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> 要計算長度的值

  encoding <String> 若是 string 是字符串,則這是它的字符編碼。 默認: 'utf8'

  返回: <Integer> string 包含的字節數

var str = '火柴';
var buf = Buffer.from(str);
console.log(str.length);//2
console.log(buf.length);//6
console.log(buf.byteLength);//6

【Buffer.compare(buf1, buf2)】

  該方法用於比較 buf1 和 buf2 ,一般用於 Buffer 實例數組的排序。 至關於調用 buf1.compare(buf2) 

  buf1 <Buffer>

  buf2 <Buffer>

  Returns: <Integer>

var buf1 = Buffer.from('1234');
var buf2 = Buffer.from('0123');
var arr = [buf1, buf2];
var result = Buffer.compare(buf1,buf2);
console.log(result);//1
console.log(arr.sort());//[ <Buffer 30 31 32 33>, <Buffer 31 32 33 34> ]

【Buffer.concat(list[, totalLength])】

  該方法返回一個合併了 list 中全部 Buffer 實例的新建的 Buffer

  list <Array> 要合併的 Buffer 實例的數組

  totalLength <Integer> 合併時 list 中 Buffer 實例的總長度

  返回: <Buffer>

  若是 list 中沒有元素、或 totalLength 爲 0 ,則返回一個新建的長度爲 0 的 Buffer 。若是沒有提供 totalLength ,則從 list 中的 Buffer 實例計算獲得。 爲了計算 totalLength 會致使須要執行額外的循環,因此提供明確的長度會運行更快

var buf1 = Buffer.alloc(10);
var buf2 = Buffer.alloc(14);
var buf3 = Buffer.alloc(18);
var totalLength = buf1.length + buf2.length + buf3.length;
console.log(totalLength);//42
var bufA = Buffer.concat([buf1, buf2, buf3], totalLength); 
console.log(bufA);//<Buffer 00 00 00 00 ...>
console.log(bufA.length);//42

【Buffer.isBuffer(obj)】

  若是 obj 是一個 Buffer 則返回 true ,不然返回 false

var buf = Buffer.alloc(5);
var str = 'test';
console.log(Buffer.isBuffer(buf));//true
console.log(Buffer.isBuffer(str));//false

 

實例方法

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

  該方法返回一個指向相同原始內存的新建的 Buffer,但作了偏移且經過 start 和 end 索引進行裁剪

  start <Integer> 新建的 Buffer 開始的位置。 默認: 0

  end <Integer> 新建的 Buffer 結束的位置(不包含)。 默認: buf.length

  返回: <Buffer>

var buffer1 =Buffer.from('test');
console.log(buffer1);//<Buffer 74 65 73 74>
var buffer2 = buffer1.slice(1,3);
console.log(buffer2);//<Buffer 65 73>
console.log(buffer2.toString());//'es'

  [注意]修改這個新建的 Buffer 切片,也會同時修改原始的 Buffer 的內存,由於這兩個對象所分配的內存是重疊的

var buffer1 =Buffer.from('test');
console.log(buffer1);//<Buffer 74 65 73 74>
var buffer2 = buffer1.slice(1,3);
console.log(buffer2);//<Buffer 65 73>
buffer2[0] = 0;
console.log(buffer1);//<Buffer 74 00 73 74>
console.log(buffer2);//<Buffer 00 73>

【buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])】

  該方法用於拷貝 buf 的一個區域的數據到 target 的一個區域,即使 target 的內存區域與 buf 的重疊

  target <Buffer> | <Uint8Array> 要拷貝進的 Buffer 或 Uint8Array

  targetStart <Integer> target 中開始拷貝進的偏移量。 默認: 0

  sourceStart <Integer> buf 中開始拷貝的偏移量。 當 targetStart 爲 undefined 時忽略。 默認: 0

  sourceEnd <Integer> buf 中結束拷貝的偏移量(不包含)。 當 sourceStart 爲 undefined 時忽略。 默認: buf.length

  返回: <Integer> 被拷貝的字節數

var buffer1 =Buffer.from('test');
var buffer2 = Buffer.alloc(5);
var len = buffer1.copy(buffer2,1,3);
console.log(buffer1);//<Buffer 74 65 73 74>
console.log(buffer2);//<Buffer 00 74 00 00 00>
console.log(len);//1

【buf.compare(target[, targetStart[, targetEnd[, sourceStart[, sourceEnd]]]])】

  該方法比較 buf 與 target,返回代表 buf 在排序上是否排在 target 以前、或以後、或相同。 對比是基於各自 Buffer 實際的字節序列

  target <Buffer> 要比較的 Buffer

  targetStart <Integer> target 中開始對比的偏移量。 默認: 0

  targetEnd <Integer> target 中結束對比的偏移量(不包含)。 當 targetStart 爲 undefined 時忽略。 默認: target.length

  sourceStart <Integer> buf 中開始對比的偏移量。 當 targetStart 爲 undefined 時忽略。 默認: 0

  sourceEnd <Integer> buf 中結束對比的偏移量(不包含)。 當 targetStart 爲 undefined 時忽略。 默認: buf.length

  返回: <Integer>

  若是 target 與 buf 相同,則返回 0 

  若是 target 排在 buf 前面,則返回 1 

  若是 target 排在 buf 後面,則返回 -1 

var buf1 = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9]);
var buf2 = Buffer.from([5, 6, 7, 8, 9, 1, 2, 3, 4]);

// 輸出: 0(buf2中的1234對比buf2中的1234)
console.log(buf1.compare(buf2, 5, 9, 0, 4));

// 輸出: -1(buf2中的567891對比buf1中的56789)
console.log(buf1.compare(buf2, 0, 6, 4));

// 輸出: 1(buf2中的1對比buf2中的6789)
console.log(buf1.compare(buf2, 5, 6, 5));

【buf.equals(otherBuffer)】

  若是 buf 與 otherBuffer 具備徹底相同的字節,則返回 true,不然返回 false

  otherBuffer <Buffer> 要比較的 Buffer

  返回: <Boolean>

var buf1 = Buffer.from('ABC');
var buf2 = Buffer.from('ABC');
var buf3 = Buffer.from('abc');
console.log(buf1.equals(buf2));//true
console.log(buf1.equals(buf3));//false

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

  value <String> | <Buffer> | <Integer> 用來填充 buf 的值

  offset <Integer> 開始填充 buf 的位置。默認: 0

  end <Integer> 結束填充 buf 的位置(不包含)。默認: buf.length

  encoding <String> 若是 value 是一個字符串,則這是它的字符編碼。 默認: 'utf8'

  返回: <Buffer> buf 的引用

  若是未指定 offset 和 end,則填充整個 buf。 這個簡化使得一個Buffer的建立與填充能夠在一行內完成

var b = Buffer.allocUnsafe(10).fill('h');
console.log(b.toString());//hhhhhhhhhh

【buf.indexOf(value[, byteOffset][, encoding])】

  value <String> | <Buffer> | <Integer> 要搜索的值

  byteOffset <Integer> buf 中開始搜索的位置。默認: 0

  encoding <String> 若是 value 是一個字符串,則這是它的字符編碼。 默認: 'utf8'

  返回: <Integer> buf 中 value 首次出現的索引,若是 buf 沒包含 value 則返回 -1

  若是value是字符串,則 value 根據 encoding 的字符編碼進行解析;若是value是Buffer,則value會被做爲一個總體使用。若是要比較部分 Buffer 可以使用 buf.slice();若是value是數值,則 value 會解析爲一個 0 至 255 之間的無符號八位整數值

var buf = Buffer.from('this is a buffer');

// 輸出: 0
console.log(buf.indexOf('this'));

// 輸出: 2
console.log(buf.indexOf('is'));

// 輸出: 8
console.log(buf.indexOf(Buffer.from('a buffer')));

// 輸出: 8
// (97 是 'a' 的十進制 ASCII 值)
console.log(buf.indexOf(97));

// 輸出: -1
console.log(buf.indexOf(Buffer.from('a buffer example')));

// 輸出: 8
console.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8)));

【buf.lastIndexOf(value[, byteOffset][, encoding])】

  與 buf.indexOf() 相似,除了 buf 是從後往前搜索而不是從前日後

var buf = Buffer.from('this buffer is a buffer');

// 輸出: 0
console.log(buf.lastIndexOf('this'));

// 輸出: 17
console.log(buf.lastIndexOf('buffer'));

// 輸出: 17
console.log(buf.lastIndexOf(Buffer.from('buffer')));

// 輸出: 15
// (97 是 'a' 的十進制 ASCII 值)
console.log(buf.lastIndexOf(97));

// 輸出: -1
console.log(buf.lastIndexOf(Buffer.from('yolo')));

// 輸出: 5
console.log(buf.lastIndexOf('buffer', 5));

// 輸出: -1
console.log(buf.lastIndexOf('buffer', 4));

【buf.includes(value[, byteOffset][, encoding])】

  該方法至關於 buf.indexOf() !== -1

  value <String> | <Buffer> | <Integer> 要搜索的值

  byteOffset <Integer> buf 中開始搜索的位置。默認: 0

  encoding <String> 若是 value 是一個字符串,則這是它的字符編碼。 默認: 'utf8'

  返回: <Boolean> 若是 buf 找到 value,則返回 true,不然返回 false

var buf = Buffer.from('this is a buffer');

// 輸出: true
console.log(buf.includes('this'));

// 輸出: true
console.log(buf.includes('is'));

// 輸出: true
console.log(buf.includes(Buffer.from('a buffer')));

// 輸出: true
// (97 是 'a' 的十進制 ASCII 值)
console.log(buf.includes(97));

// 輸出: false
console.log(buf.includes(Buffer.from('a buffer example')));

// 輸出: true
console.log(buf.includes(Buffer.from('a buffer example').slice(0, 8)));

// 輸出: false
console.log(buf.includes('this', 4));
相關文章
相關標籤/搜索