深入浅出:Node.js 中的 Buffer

291 阅读3分钟

在 Node.js 中,Buffer 是处理二进制数据的重要工具。无论是读取文件、处理网络请求,还是处理流数据,Buffer 都扮演着至关重要的角色。在 JavaScript 中,字符串通常是以字符为单位进行处理的,而在与外部系统进行交互时(如读取文件、发送网络请求),往往需要处理原始的二进制数据。Buffer 就是为了弥补 JavaScript 对二进制数据处理的不足而诞生的。

Buffer 与字符编码

Buffer 实例一般用于表示编码字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六进制编码的数据。 通过使用显式的字符编码,就可以在 Buffer 实例与普通的 JavaScript 字符串之间进行相互转换。Node.js 缓冲区接受其收到的编码字符串的所有大小写变体。例如,UTF-8 可以指定为'utf8''UTF8''uTf8'

Node.js 目前支持的字符编码包括:

  • 'utf8'(别名:'utf-8'):多字节编码的 Unicode 字符。许多网页和其他文档格式都使用UTF-8。这是默认的字符编码。当将 解码Buffer为不完全包含有效 UTF-8 数据的字符串时,将使用 Unicode 替换字符U+FFFD� 来表示这些错误。

  • 'utf16le'(别名:'utf-16le'):多字节编码的 Unicode 字符。与 不同'utf8',字符串中的每个字符将使用 2 个或 4 个字节进行编码。Node.js 仅支持UTF-16的 小端变体。

  • 'latin1':Latin-1 代表ISO-8859-1U+0000 。此字符编码仅支持从到 的Unicode 字符U+00FF。每个字符都使用单个字节进行编码。不符合该范围的字符将被截断并映射到该范围内的字符。

  • 'base64':Base64编码。base64 编码字符串中包含的空格、制表符和换行符等空白字符将被忽略。

  • 'base64url':base64url编码,此编码也将正确接受常规 base64 编码字符串。将编码Buffer为字符串时,此编码将省略填充

  • 'hex':将每个字节编码为两个十六进制字符。

  • 'ascii':仅适用于 7 位ASCII数据。

  • 'binary':的别名'latin1'。此编码的名称可能非常具有误导性,因为此处列出的所有编码都在字符串和二进制数据之间进行转换。对于在字符串和Buffers 之间进行转换,通常'utf8'是正确的选择。

  • 'ucs2''ucs-2': 的别名'utf16le'。UCS-2 曾指代 UTF-16 的一种变体,不支持代码点大于 U+FFFF 的字符。在 Node.js 中,这些代码点始终受支持。

如何创建 Buffer?

创建 Buffer 有几种常见的方式:

  1. 通过指定大小创建空的 Buffer

    const buf = Buffer.alloc(10); // 创建一个包含10个字节的空Buffer
    console.log(buf); // 输出: <Buffer 00 00 00 00 00 00 00 00 00 00>
    
  2. 通过已有的数据创建 Buffer

    const buf = Buffer.from('Hello, Node.js!');
    console.log(buf); // 输出: <Buffer 48 65 6c 6c 6f 2c 20 4e 6f 64 65 2e 6a 73 21>
    
  3. 通过指定数组创建 Buffer

    const buf = Buffer.from([72, 101, 108, 108, 111]);
    console.log(buf.toString()); // 输出: "Hello"
    

Buffer 的常用方法

  1. toString([encoding], [start], [end])
    Buffer 转换为字符串。encoding 这边就会之前介绍的各种编码。

    const buf = Buffer.from('Hello, World!');
    console.log(buf.toString()); // 输出: "Hello, World!"
    console.log(buf.toString('utf8')); // 输出: "Hello, World!"
    console.log(buf.toString('hex')); // 输出: "48656c6c6f2c20576f726c6421"
    console.log(buf.toString('base64')); // 输出: "SGVsbG8sIFdvcmxkIQ=="
    console.log(buf.toString('ascii')); // 输出: "Hello, World!"
    
  2. buf.write(string, [offset], [length], [encoding])
    将字符串写入 Buffer 中,指定偏移量和编码。

    const buf = Buffer.alloc(20);
    buf.write('Hello');
    console.log(buf.toString()); // 输出: "Hello"
    
  3. buf.slice([start], [end])
    创建一个新的 Buffer,它是原 Buffer 的一部分。

    const buf = Buffer.from('Hello, Node.js!');
    const slice = buf.slice(0, 5);
    console.log(slice.toString()); // 输出: "Hello"
    
  4. buf.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd])
    将数据从一个 Buffer 复制到另一个 Buffer 中。

    const buf1 = Buffer.from('Hello');
    const buf2 = Buffer.alloc(5);
    buf1.copy(buf2);
    console.log(buf2.toString()); // 输出: "Hello"
    
  5. buf.equals(otherBuffer)
    判断两个 Buffer 是否相等。

    const buf1 = Buffer.from('Hello');
    const buf2 = Buffer.from('Hello');
    console.log(buf1.equals(buf2)); // 输出: true