溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何在node.JS中使用二進(jìn)制操作模塊

發(fā)布時(shí)間:2021-03-18 16:21:39 來源:億速云 閱讀:247 作者:Leah 欄目:web開發(fā)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)如何在node.JS中使用二進(jìn)制操作模塊,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

在ES6引入TypedArray之前,JavaScript語言沒有讀取或操作二進(jìn)制數(shù)據(jù)流的機(jī)制。Buffer類被引入作為Nodejs的API的一部分,使其可以在TCP流和文件系統(tǒng)操作等場(chǎng)景中處理二進(jìn)制數(shù)據(jù)流?,F(xiàn)在TypedArray已經(jīng)被添加進(jìn)ES6中,Buffer類以一種更優(yōu)與更適合Node.js用例的方式實(shí)現(xiàn)了Uint8Array。

Buffer對(duì)象概述

由于應(yīng)用場(chǎng)景不同,在Node中,應(yīng)用需要處理網(wǎng)絡(luò)協(xié)議、操作數(shù)據(jù)庫、處理圖片、接收上傳文件等,在網(wǎng)絡(luò)流和文件的操作中,還要處理大量二進(jìn)制數(shù)據(jù),JavaScript自有的字符串遠(yuǎn)遠(yuǎn)不能滿足這些需求,于是Buffer對(duì)象應(yīng)運(yùn)而生

Buffer是一個(gè)典型的JavaScript與C++結(jié)合的模塊,它將性能相關(guān)部分用C++實(shí)現(xiàn),將非性能相關(guān)的部分用JavaScript實(shí)現(xiàn)。Buffer類的實(shí)例類似于整數(shù)數(shù)組,除了其是大小固定的、且在V8堆外分配物理內(nèi)存。Buffer的大小在其創(chuàng)建時(shí)就已確定,且不能調(diào)整大小

由于Buffer太過常見,Node在進(jìn)程啟動(dòng)時(shí)就已經(jīng)加載了它,并將其放在全局對(duì)象(global)上。所以在使用Buffer時(shí),無須通過require()即可直接使用

/*
{ [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);

創(chuàng)建Buffer對(duì)象

在 Node.js v6之前的版本中,Buffer實(shí)例是通過Buffer構(gòu)造函數(shù)創(chuàng)建的,它根據(jù)提供的參數(shù)返回不同的 Buffer,而新版本的nodejs則提供了對(duì)應(yīng)的方法

1、new Buffer(size)。傳一個(gè)數(shù)值作為第一個(gè)參數(shù)給Buffer()(如new Buffer(10)),則分配一個(gè)指定大小的新建的Buffer對(duì)象

分配給這種Buffer實(shí)例的內(nèi)存是未初始化的(沒有用0填充)。雖然這樣的設(shè)計(jì)使得內(nèi)存的分配非???,但已分配的內(nèi)存段可能包含潛在的敏感舊數(shù)據(jù)

這種Buffer實(shí)例必須手動(dòng)地被初始化,可以使用buf.fill(0)或?qū)憹M這個(gè)Buffer。雖然這種行為是為了提高性能而有意為之的,但開發(fā)經(jīng)驗(yàn)表明,創(chuàng)建一個(gè)快速但未初始化的Buffer與創(chuàng)建一個(gè)慢點(diǎn)但更安全的Buffer之間需要有更明確的區(qū)分

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>

[注意]當(dāng)我們?yōu)橐粋€(gè)Buffer對(duì)象分配空間大小后,其長(zhǎng)度就是固定的,不能更改

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)

 在新版本中,由Buffer.allocUnsafe(size)方法替代,來分配一個(gè)大小為 size 字節(jié)的新建的沒有用0填充的Buffer。可以使用buf.fill(0)初始化Buffer實(shí)例為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)方法可以生成一個(gè)安全的buffer對(duì)象,參數(shù)size <Integer> 新建的 Buffer 期望的長(zhǎng)度;fill <String> | <Buffer> | <Integer> 用來預(yù)填充新建的 Buffer 的值。 默認(rèn): 0;encoding <String> 如果 fill 是字符串,則該值是它的字符編碼。 默認(rèn): 'utf8'

分配一個(gè)大小為 size 字節(jié)的新建的 Buffer 。 如果 fill 為 undefined ,則該 Buffer 會(huì)用 0 填充

var buf = Buffer.alloc(5);

console.log(buf);//<Buffer 00 00 00 00 00>

2、new Buffer(array或buffer)。傳一個(gè)數(shù)組或Buffer作為第一個(gè)參數(shù),則將所傳對(duì)象的數(shù)據(jù)拷貝到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>

3、new Buffer(string[, encoding])。第一個(gè)參數(shù)是字符串,第二個(gè)參數(shù)是編碼方式,默認(rèn)是'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 數(shù)據(jù)。如果設(shè)置去掉高位的話,這種編碼是非??斓?。

'utf8' - 多字節(jié)編碼的 Unicode 字符。許多網(wǎng)頁和其他文檔格式都使用 UTF-8 。

'utf16le' - 2 或 4 個(gè)字節(jié),小字節(jié)序編碼的 Unicode 字符。支持代理對(duì)(U+10000 至 U+10FFFF)。

'ucs2' - 'utf16le' 的別名。

'base64' - Base64 編碼。當(dāng)從字符串創(chuàng)建 Buffer 時(shí),這種編碼可接受“URL 與文件名安全字母表”。

'latin1' - 一種把 Buffer 編碼成一字節(jié)編碼的字符串的方式。

'binary' - 'latin1' 的別名。

'hex' - 將每個(gè)字節(jié)編碼為兩個(gè)十六進(jìn)制字符。

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

4、new Buffer(arrayBuffer[, byteOffset [, length]])。參數(shù)arrayBuffer <ArrayBuffer> 一個(gè) ArrayBuffer,或一個(gè) TypedArray 的 .buffer 屬性;byteOffset <Integer> 開始拷貝的索引。默認(rèn)為 0;length <Integer> 拷貝的字節(jié)數(shù)。默認(rèn)為 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對(duì)象類似于數(shù)組,它的元素為16進(jìn)制的兩位數(shù),即0到255的數(shù)值

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

長(zhǎng)度

不同編碼的字符串占用的元素個(gè)數(shù)各不相同,中文字在UTF-8編碼下占用3個(gè)元素,字母和半角標(biāo)點(diǎn)符號(hào)占用1個(gè)元素

var buf = Buffer.from('match');

console.log(buf.length);//5

var buf = Buffer.from('火柴');

console.log(buf.length);//6

下標(biāo)

Buffer受Array類型的影響很大,可以訪問length屬性得到長(zhǎng)度,也可以通過下標(biāo)訪問元素

var buf = Buffer.alloc(10); 

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

上述代碼分配了一個(gè)長(zhǎng)10字節(jié)的Buffer對(duì)象。我們可以通過下標(biāo)對(duì)它進(jìn)行賦值

buf[0] = 100;

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

要注意的是,給元素的賦值如果小于0,就將該值逐次加256,直到得到一個(gè)0到255之間的整數(shù)。如果得到的數(shù)值大于255,就逐次減256,直到得到0~255區(qū)間內(nèi)的數(shù)值。如果是小數(shù),舍棄小數(shù)部分,只保留整數(shù)部分

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

通常地,創(chuàng)建的buffer對(duì)象的內(nèi)容是其uft-8字符編碼

var buf = Buffer.from('match'); 

console.log(buf); //<Buffer 6d 61 74 63 68>

如果要訪問其對(duì)應(yīng)的字符,則需要使用字符串的fromCharCode()方法

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

內(nèi)存分配

Buffer對(duì)象的內(nèi)存分配不是在V8的堆內(nèi)存中,而是在Node的C++層面實(shí)現(xiàn)內(nèi)存的申請(qǐng)的。因?yàn)樘幚泶罅康淖止?jié)數(shù)據(jù)不能采用需要一點(diǎn)內(nèi)存就向操作系統(tǒng)申請(qǐng)一點(diǎn)內(nèi)存的方式,這可能造成大量的內(nèi)存申請(qǐng)的系統(tǒng)調(diào)用,對(duì)操作系統(tǒng)有一定壓力。為此Node在內(nèi)存的使用上應(yīng)用的是在C++層面申請(qǐng)內(nèi)存、在JavaScript中分配內(nèi)存的策略

為了高效地使用申請(qǐng)來的內(nèi)存,Node采用了slab分配機(jī)制。slab是一種動(dòng)態(tài)內(nèi)存管理機(jī)制,最早誕生于SunOS操作系統(tǒng)(Solaris)中,目前在一些*nix操作系統(tǒng)中有廣泛的應(yīng)用,如FreeBSD和Linux。簡(jiǎn)單而言,slab就是一塊申請(qǐng)好的固定大小的內(nèi)存區(qū)域。slab具有如下3種狀態(tài):full:完全分配狀態(tài);partial:部分分配狀態(tài);empty:沒有被分配狀態(tài)

當(dāng)我們需要一個(gè)Buffer對(duì)象,可以通過以下方式分配指定大小的Buffer對(duì)象:

new Buffer(size);//舊

Buffer.alloc(size);//新

poolSize

poolSize屬性是用于決定預(yù)分配的、內(nèi)部 Buffer 實(shí)例池的大小的字節(jié)數(shù)。默認(rèn)地,Node以8KB為界限來區(qū)分Buffer是大對(duì)象還是小對(duì)象:

Buffer.poolSize = 8 * 1024;

這個(gè)8KB的值也就是每個(gè)slab的大小值,在JavaScript層面,以它作為單位單元進(jìn)行內(nèi)存的分配

1、分配小Buffer對(duì)象

如果指定Buffer的大小少于8KB,Node會(huì)按照小對(duì)象的方式進(jìn)行分配。Buffer的分配過程中主要使用一個(gè)局部變量pool作為中間處理對(duì)象,處于分配狀態(tài)的slab單元都指向它。以下是分配一個(gè)全新的slab單元的操作,它會(huì)將新申請(qǐng)的SlowBuffer對(duì)象指向它:

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

構(gòu)造小Buffer對(duì)象時(shí)的代碼如下:

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

這次構(gòu)造將會(huì)去檢查pool對(duì)象,如果pool沒有被創(chuàng)建,將會(huì)創(chuàng)建一個(gè)新的slab單元指向它:

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

同時(shí)當(dāng)前Buffer對(duì)象的parent屬性指向該slab,并記錄下是從這個(gè)slab的哪個(gè)位置(offset)開始使用的,slab對(duì)象自身也記錄被使用了多少字節(jié),代碼如下:

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

這時(shí)候的slab狀態(tài)為partial。當(dāng)再次創(chuàng)建一個(gè)Buffer對(duì)象時(shí),構(gòu)造過程中將會(huì)判斷這個(gè)slab的剩余空間是否足夠。如果足夠,使用剩余空間,并更新slab的分配狀態(tài)。下面的代碼創(chuàng)建了一個(gè)新的Buffer對(duì)象,它會(huì)引起一次slab分配:

new Buffer(3000);//舊

Buffer.alloc(3000);//新

如果slab剩余的空間不夠,將會(huì)構(gòu)造新的slab,原slab中剩余的空間會(huì)造成浪費(fèi)。例如,第一次構(gòu)造1字節(jié)的Buffer對(duì)象,第二次構(gòu)造8192字節(jié)的Buffer對(duì)象,由于第二次分配時(shí)slab中的空間不夠,所以創(chuàng)建并使用新的slab,第一個(gè)slab的8KB將會(huì)被第一個(gè)1字節(jié)的Buffer對(duì)象獨(dú)占。下面的代碼一共使用了兩個(gè)slab單元:

new Buffer(1);//舊

Buffer.alloc(1);//新

new Buffer(8192);//舊

Buffer.alloc(8192);//新

要注意的是,由于同一個(gè)slab可能分配給多個(gè)Buffer對(duì)象使用,只有這些小Buffer對(duì)象在作用域釋放并都可以回收時(shí),slab的8KB空間才會(huì)被回收。盡管創(chuàng)建了1個(gè)字節(jié)的Buffer對(duì)象,但是如果不釋放它,實(shí)際可能是8KB的內(nèi)存沒有釋放

2、分配大Buffer對(duì)象

如果需要超過8KB的Buffer對(duì)象,將會(huì)直接分配一個(gè)SlowBuffer對(duì)象作為slab單元,這個(gè)slab單元將會(huì)被這個(gè)大Buffer對(duì)象獨(dú)占

// Big buffer, just alloc one

this.parent = new SlowBuffer(this.length); 

this.offset = 0;

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

上面提到的Buffer對(duì)象都是JavaScript層面的,能夠被V8的垃圾回收標(biāo)記回收。但是其內(nèi)部的parent屬性指向的SlowBuffer對(duì)象卻來自于Node自身C++中的定義,是C++層面上的Buffer對(duì)象,所用內(nèi)存不在V8的堆中

綜上,真正的內(nèi)存是在Node的C++層面提供的,JavaScript層面只是使用它。當(dāng)進(jìn)行小而頻繁的Buffer操作時(shí),采用slab的機(jī)制進(jìn)行預(yù)先申請(qǐng)和事后分配,使得JavaScript到操作系統(tǒng)之間不必有過多的內(nèi)存申請(qǐng)方面的系統(tǒng)調(diào)用。對(duì)于大塊的Buffer而言,則直接使用C++層面提供的內(nèi)存,而無需細(xì)膩的分配操作

轉(zhuǎn)換

Buffer對(duì)象可以與字符串之間相互轉(zhuǎn)換。目前支持的字符串編碼類型有如下幾種:ASCII、UTF-8、UTF-16LE/UCS-2、Base64、Binary、Hex

write()

一個(gè)Buffer對(duì)象可以存儲(chǔ)不同編碼類型的字符串轉(zhuǎn)碼的值,調(diào)用write()方法可以實(shí)現(xiàn)該目的

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

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

offset <Integer> 開始寫入 string 的位置。默認(rèn): 0

length <Integer> 要寫入的字節(jié)數(shù)。默認(rèn): buf.length - offset

encoding <String> string 的字符編碼。默認(rèn): 'utf8';返回: <Integer> 寫入的字節(jié)數(shù)

根據(jù) encoding 的字符編碼寫入 string 到 buf 中的 offset 位置。 length 參數(shù)是寫入的字節(jié)數(shù)。 如果 buf 沒有足夠的空間保存整個(gè)字符串,則只會(huì)寫入 string 的一部分。 只部分解碼的字符不會(huì)被寫入

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

由于可以不斷寫入內(nèi)容到Buffer對(duì)象中,并且每次寫入可以指定編碼,所以Buffer對(duì)象中可以存在多種編碼轉(zhuǎn)化后的內(nèi)容。需要小心的是,每種編碼所用的字節(jié)長(zhǎng)度不同,將Buffer反轉(zhuǎn)回字符串時(shí)需要謹(jǐn)慎處理

toString()

實(shí)現(xiàn)Buffer向字符串的轉(zhuǎn)換也十分簡(jiǎn)單,Buffer對(duì)象的toString()可以將Buffer對(duì)象轉(zhuǎn)換為字符串

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

encoding - 使用的編碼。默認(rèn)為 'utf8'

start - 指定開始讀取的索引位置,默認(rèn)為 0

end - 結(jié)束位置,默認(rèn)為緩沖區(qū)的末尾

返回 - 解碼緩沖區(qū)數(shù)據(jù)并使用指定的編碼返回字符串

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 轉(zhuǎn)換為 JSON 對(duì)象

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對(duì)象支持的編碼類型有限,只有少數(shù)的幾種編碼類型可以在字符串和Buffer之間轉(zhuǎn)換。為此,Buffer提供了一個(gè)isEncoding()函數(shù)來判斷編碼是否支持轉(zhuǎn)換

Buffer.isEncoding(encoding)

將編碼類型作為參數(shù)傳入上面的函數(shù),如果支持轉(zhuǎn)換返回值為true,否則為false。很遺憾的是,在中國(guó)常用的GBK、GB2312和BIG-5編碼都不在支持的行列中

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

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

Buffer類方法

Buffer.byteLength(string[, encoding])

Buffer.byteLength()方法返回一個(gè)字符串的實(shí)際字節(jié)長(zhǎng)度。 這與 String.prototype.length 不同,因?yàn)槟欠祷刈址淖址麛?shù)

string <String> | <Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> 要計(jì)算長(zhǎng)度的值

encoding <String> 如果 string 是字符串,則這是它的字符編碼。 默認(rèn): 'utf8'

返回: <Integer> string 包含的字節(jié)數(shù)

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 實(shí)例數(shù)組的排序。 相當(dāng)于調(diào)用 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])

該方法返回一個(gè)合并了 list 中所有 Buffer 實(shí)例的新建的 Buffer

list <Array> 要合并的 Buffer 實(shí)例的數(shù)組

totalLength <Integer> 合并時(shí) list 中 Buffer 實(shí)例的總長(zhǎng)度

返回: <Buffer>

如果 list 中沒有元素、或 totalLength 為 0 ,則返回一個(gè)新建的長(zhǎng)度為 0 的 Buffer 。如果沒有提供 totalLength ,則從 list 中的 Buffer 實(shí)例計(jì)算得到。 為了計(jì)算 totalLength 會(huì)導(dǎo)致需要執(zhí)行額外的循環(huán),所以提供明確的長(zhǎng)度會(huì)運(yùn)行更快

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 是一個(gè) Buffer 則返回 true ,否則返回 false

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

實(shí)例方法

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

該方法返回一個(gè)指向相同原始內(nèi)存的新建的 Buffer,但做了偏移且通過 start 和 end 索引進(jìn)行裁剪

start <Integer> 新建的 Buffer 開始的位置。 默認(rèn): 0

end <Integer> 新建的 Buffer 結(jié)束的位置(不包含)。 默認(rèn): 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'

[注意]修改這個(gè)新建的 Buffer 切片,也會(huì)同時(shí)修改原始的 Buffer 的內(nèi)存,因?yàn)檫@兩個(gè)對(duì)象所分配的內(nèi)存是重疊的

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 的一個(gè)區(qū)域的數(shù)據(jù)到 target 的一個(gè)區(qū)域,即便 target 的內(nèi)存區(qū)域與 buf 的重疊

target <Buffer> | <Uint8Array> 要拷貝進(jìn)的 Buffer 或 Uint8Array

targetStart <Integer> target 中開始拷貝進(jìn)的偏移量。 默認(rèn): 0

sourceStart <Integer> buf 中開始拷貝的偏移量。 當(dāng) targetStart 為 undefined 時(shí)忽略。 默認(rèn): 0

sourceEnd <Integer> buf 中結(jié)束拷貝的偏移量(不包含)。 當(dāng) sourceStart 為 undefined 時(shí)忽略。 默認(rèn): buf.length

返回: <Integer> 被拷貝的字節(jié)數(shù)

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 之前、或之后、或相同。 對(duì)比是基于各自 Buffer 實(shí)際的字節(jié)序列

target <Buffer> 要比較的 Buffer

targetStart <Integer> target 中開始對(duì)比的偏移量。 默認(rèn): 0

targetEnd <Integer> target 中結(jié)束對(duì)比的偏移量(不包含)。 當(dāng) targetStart 為 undefined 時(shí)忽略。 默認(rèn): target.length

sourceStart <Integer> buf 中開始對(duì)比的偏移量。 當(dāng) targetStart 為 undefined 時(shí)忽略。 默認(rèn): 0

sourceEnd <Integer> buf 中結(jié)束對(duì)比的偏移量(不包含)。 當(dāng) targetStart 為 undefined 時(shí)忽略。 默認(rèn): 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對(duì)比buf2中的1234)
console.log(buf1.compare(buf2, 5, 9, 0, 4));
// 輸出: -1(buf2中的567891對(duì)比buf1中的56789)
console.log(buf1.compare(buf2, 0, 6, 4));
// 輸出: 1(buf2中的1對(duì)比buf2中的6789)
console.log(buf1.compare(buf2, 5, 6, 5));

buf.equals(otherBuffer)

如果 buf 與 otherBuffer 具有完全相同的字節(jié),則返回 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 的位置。默認(rèn): 0

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

encoding <String> 如果 value 是一個(gè)字符串,則這是它的字符編碼。 默認(rèn): 'utf8'

返回: <Buffer> buf 的引用

如果未指定 offset 和 end,則填充整個(gè) buf。 這個(gè)簡(jiǎn)化使得一個(gè)Buffer的創(chuàng)建與填充可以在一行內(nèi)完成

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

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

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

byteOffset <Integer> buf 中開始搜索的位置。默認(rèn): 0

encoding <String> 如果 value 是一個(gè)字符串,則這是它的字符編碼。 默認(rèn): 'utf8'

返回: <Integer> buf 中 value 首次出現(xiàn)的索引,如果 buf 沒包含 value 則返回 -1

如果value是字符串,則 value 根據(jù) encoding 的字符編碼進(jìn)行解析;如果value是Buffer,則value會(huì)被作為一個(gè)整體使用。如果要比較部分 Buffer 可使用 buf.slice();如果value是數(shù)值,則 value 會(huì)解析為一個(gè) 0 至 255 之間的無符號(hào)八位整數(shù)值

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' 的十進(jìn)制 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' 的十進(jìn)制 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])

該方法相當(dāng)于 buf.indexOf() !== -1

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

byteOffset <Integer> buf 中開始搜索的位置。默認(rèn): 0

encoding <String> 如果 value 是一個(gè)字符串,則這是它的字符編碼。 默認(rèn): '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' 的十進(jìn)制 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

上述就是小編為大家分享的如何在node.JS中使用二進(jìn)制操作模塊了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI