首頁  >  文章  >  web前端  >  詳解Node.js中Buffer物件的操作(建立、讀寫)

詳解Node.js中Buffer物件的操作(建立、讀寫)

青灯夜游
青灯夜游轉載
2021-12-23 18:55:513557瀏覽

這篇文章帶大家了解一下Node中的Buffer對象,介紹一下創建 Buffer 對象、讀 Buffer 對象、寫 Buffer 對象的方法,希望對大家有幫助!

詳解Node.js中Buffer物件的操作(建立、讀寫)

Buffer 是Node.js 的內建類型,它是用來表示記憶體中一塊區域的,用來保存二進位數據,可以將它看做為一個二進制數組。

Buffer 可以用來表示圖片、影片這樣的二進位數據,另外我們從文件中讀取到的也是Buffer 類型的數據,從網路接收的數據也是Buffer 類型的數據,所以學習Buffer 還是很有必要的。

Buffer 位於全域作用域中,所以不需要透過 require('buffer') 來引入 Buffer。

建立Buffer 物件

alloc

我們可以透過Buffer.alloc(size, [fill], [encoding]) 來分配一個size 位元組大小的內存,也可以接收兩個可選參數

  • fill:使用fill 來填充Buffer 中的每一個位元組
  • encoding:如果fill 為字串,那麼使用encoding 來對字串進行編碼為二進位

當不指定fill 參數,預設為填滿0。

const buf1 = Buffer.alloc(5);
console.log(buf1); // <Buffer 00 00 00 00 00>

const buf2 = Buffer.alloc(10, 1);
console.log(buf2); // <Buffer 01 01 01 01 01 01 01 01 01 01>

const buf3 = Buffer.alloc(12, "hello world!", "utf-8");
console.log(buf3); // <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64 21>

我們也可以使用allocUnsafe(size) 來分配指定大小的內存,不過不會預設填入0,其中的內容不確定

const buf = Buffer.allocUnsafe(5);
console.log(buf); // <Buffer c0 84 7c 2a 7b>

我們可以透過fill(fill, encoding) 方法為Buffer 物件填入指定值

const buf = Buffer.allocUnsafe(5);
buf.fill(0);
console.log(buf); // <Buffer 00 00 00 00 00>

from

我們也可以透過Buffer.from( ) 方法來建立一個Buffer 對象,from 方法可以接收的參數包括數組,字串,Buffer 對象,對像等型別。

接收一個整形數組,數組中的整數應該在0~255 之間,超出此範圍的數字將會被截斷

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

我們還可以像其中傳入一個字串,並指定編碼,它會使用指定編碼將字串編碼為二進制,如果不指定編碼的話,預設為編碼為utf-8

const buf = Buffer.from("hello", "utf-8");
console.log(buf); // <Buffer 68 65 6c 6c 6f>

from 方法還可以接收一個Buffer 對象,它會拷貝傳入的Buffer 對像中的資料到新的Buffer 對象

const buf1 = Buffer.from("hello", "utf-8");
const buf2 = Buffer.from(buf1);

console.log(buf1 === buf2); // false
console.log(buf2.toString()); // hello

from 方法也可以接收一個對象,當傳入對象,首先會將對象轉化為原始值,然後根據原始值轉換為對應的二進制數組

let obj = {
  [Symbol.toPrimitive](hint) {
    return "a";
  },
};

const buf = Buffer.from(obj);
console.log(buf.toString()); // a

Buffer 對象的屬性

length

透過length 屬性可以知道Buffer 數組的長度

const buf = Buffer.from("Hello World!");

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

buffer

Buffer 物件內部實際儲存資料的是一個ArrayBuffer 的對象,透過buffer 屬性可以得到這個物件

const buf = Buffer.alloc(5);

console.log(buf.buffer); // ArrayBuffer { [Uint8Contents]: <00 00 00 00 00>, byteLength: 5 }

讀Buffer 物件

本節介紹如何存取Buffer 物件中的內容。

下標

在文章的開頭提過,我們可以將Buffer 物件看做是一個二進位數組,既然是數組,那麼就可以透過下標的形式來存取數組中的內容。

const buf = Buffer.from([1, 2, 3, 4, 5]);
console.log(buf[0]); // 1
console.log(buf[5]); // undefined

它們會以補碼的形式解析字節,並傳回對應的數字。

readXxx

我們也可以透過buf.readInt8() buf.readInt16() buf. readUint8() buf.readUint16() 等方法存取Buffer 物件中的內容。

const buf = Buffer.from([1, 2, 3, 4, 5]);
console.log(buf.readInt8(2)); // 3

// 访问超出范围的内容,会抛出 RangeError
console.log(buf.readInt8(5)); // RangeError [ERR_OUT_OF_RANGE]: The value of "offset" is out of range.

迭代器

Buffer 物件的迭代器同數組的迭代器相同,也有三個迭代器,分別是

  • entries
  • keys
  • values

我們透過遍歷迭代器來存取Buffer 物件中的內容。

const buf = Buffer.from([3, 4, 2]);

for (let entry of buf.entries()) {
  // 数组的一个元素为下标,第二个元素为下标对应的元素
  console.log(entry); // [ 0, 3 ]
                      // [ 1, 4 ]
                      // [ 2, 2 ]
}
for (let key of buf.keys()) {
  console.log(key); // 0
                    // 1
                    // 2
}
for (let value of buf.values()) {
  console.log(value); // 3
                      // 4
                      // 2
}

寫 Buffer 物件

本小節講解如何向 Buffer 物件中寫入內容。

下標

我們可以直接透過下標來改變Buffer 物件中的內容

const buf = Buffer.from([1, 2, 3]);

// 通过下标设置值
buf[0] = 4;

console.log(buf); // <Buffer 04 02 03>

write

我們可以透過write(string, [offset], [length], [encoding]) 方法向Buffer 中寫入字串:

  • string:表示要寫入的字串
  • offset:偏移量,即跳過offset 個位元組開始寫入,預設為0
  • length:要寫入的最大位元組數,不超過buf.length - offset,預設值為buf.length - offset
  • encoding:指定編碼,預設為utf-8

此方法傳回已寫入的位元組數。

const buf = Buffer.from([1, 2, 3, 4]);

// 跳过 1 个字节开始写入,1hi4
buf.write("hi", 1);

console.log(buf); // <Buffer 01 68 69 04>

writeXxx

同readXxx,我們可以透過writeInt8() 方法向buf 中寫入數據,方法接收兩個參數:

  • value:要写入的值
  • offset:偏移量,默认为 0
const buf = Buffer.alloc(5);

buf.writeInt8(1, 0);
buf.writeInt8(3, 1);

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

踩坑:没有 writeInt16(),不过有 writeInt16BE()writeInt16LE(),分别代表以大端序、小端序写入。

其他方法

isBuffer

该方法接收一个对象,用来判断该对象是不是一个 Buffer 对象

let obj1 = {};
let obj2 = Buffer.alloc(3);

console.log(Buffer.isBuffer(obj1)); // false
console.log(Buffer.isBuffer(obj2)); // true

isEncoding

该方法接收一个代表编码的字符串,返回 Buffer 是否支持该种编码,如果支持则返回 true,否则返回 false

console.log(Buffer.isEncoding("utf-8")); // true
console.log(Buffer.isEncoding("utf8"));  // true
console.log(Buffer.isEncoding("hex"));   // true
console.log(Buffer.isEncoding("latin")); // false
console.log(Buffer.isEncoding("gbk"));   // false

slice

slice(start, end) 可以裁切原有的 Buffer 对象,返回一个新的 Buffer 对象,其中 start 和 end 代表裁切的起始位置和结束位置,左闭右开 [start, end),这两个参数是可选的,start 默认为 0,end 默认为 buf.length。返回的 Buffer 对象与原先对象引用的是同一块内存,即它们的 buffer 属性是一样的。

const buffer = Buffer.from("hello world!");

const newBuffer = buffer.slice(6); // 裁切 6 以后的内容到新数组
console.log(newBuffer.toString()); // world!

console.log(buffer.buffer === newBuffer.buffer); // true

subarray

subarray(start, end) 几乎可以看做等同于 slice 方法了,二者的语义不同,不过行为确实一致的,subarray 的语义表示返回原数组的某个范围的子数组,而 slice 的语义表示的裁切。同样 subarray 返回新的 Buffer 对象,并且返回的 Buffer 对象的 buffer 与原 Buffer 对象的 buffer 属性是相同的。

const buffer = Buffer.from("hello world!");

const newBuffer = buffer.subarray(6);
console.log(newBuffer.toString()); // world!

console.log(buffer.buffer === newBuffer.buffer); // true

copy

copy(target, [targetStart], [sourceStart], [sourceEnd]) 方法是将 source 从 sourceStart 到 sourceEnd 的内容复制到 target 从 targetStart 的位置,见下动图

詳解Node.js中Buffer物件的操作(建立、讀寫)

除了 target 以外,其他三个参数都是可选参数,targetStart 与 sourceStart 的默认值为 0,sourceEnd 的默认值为 buf.length.

const buf1 = Buffer.from("HelloWorld");
const buf2 = Buffer.alloc(8);

buf1.copy(buf2, 0, 1, 9);

console.log(buf2.toString()); // elloWorl

includes

buf.includes(value, [offset], [encoding]) 方法的作用是判断 value 是否在 buf 中。

value 可以是一个字符串,也可以是一个 Buffer 对象,也可以是一个整数;offset 用来规定查找范围,表示从 offset 处开始查找,默认为 0;enconding 表示编码,默认为 utf-8

const buf = Buffer.from("HelloWorld");

// 默认从 0 开始搜索
console.log(buf.includes("H")); // true
// 从 1 开始搜索,后面不包含 H
console.log(buf.includes("H", 1)); // false

console.log(buf.includes(Buffer.from("Hello"))); // true

// H 对应的 utf-8 编码为 72
console.log(buf.includes(72)); // true

indexOf

buf.indexOf(value, [offset], [encoding]) 是用来查找 value 在 buf 中的下标的,参数的含义同 includes 方法相同,如果在 buf 找不到 value,那么会返回 -1,所以 includes(value) 方法其实就相当于 indexOf(value) !== -1

const buf = Buffer.from("HelloWorld");

console.log(buf.indexOf("H")); // 0
console.log(buf.indexOf("H", 1)); // -1
console.log(buf.indexOf(Buffer.from("World"))); // 5
console.log(buf.indexOf(72)); // 0

equals

buf.equals(otherBuffer) 是比较两个 Buffer 对象的字节是否完全相同,如果相同,则返回 true,否则返回 false

const buf1 = Buffer.alloc(5);
const buf2 = Buffer.alloc(5);
const buf3 = Buffer.allocUnsafe(5);

console.log(buf1.equals(buf2)); // true
console.log(buf1.equals(buf3)); // false

更多node相关知识,请访问:nodejs 教程!!

以上是詳解Node.js中Buffer物件的操作(建立、讀寫)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除