Buffer的使用

189 阅读3分钟

「本文正在参与技术专题征文Node.js进阶之路,点击查看详情

前言

大家好呀,我是L同学。今天我们来学习下Buffer的使用。

在计算机中,文字、图片、视频、音频等内容最终都会使用二进制来表示。

在服务器端我们操作二进制数据是通过Buffer完成的。Node提供给了我们一个类Buffer,并且是全局的。

在Buffer中存储的是二进制数据。它是一个存储二进制的数组,数组中的每一项可以保存8位二进制,即一个字节(byte)。

创建Buffer

我们想要把字符串存储到Buffer中,那么该怎么做呢?

方式一:通过new来进行创建

前面我们讲到了Buffer是个类,我们可以通过new来创建一个buffer。

const message = 'hello'

const buffer = new Buffer(message)
console.log(buffer);

我们可以看到buffer数组中有5项,正好对应hello中的每个字母。前面我们提到buffer数组中的每一项存储的是8位二进制,那么打印出来的每一项为什么不是8位呢?这边显示的是16进制。 image.png 但是同时也打印出了警告:通过new进行创建的方式已经过期了,不推荐使用这种方式。

方式二:通过Buffer.from()进行创建

const message = 'hello'

const buffer = Buffer.from(message)
console.log(buffer);

image.png

上述的字符串是英文,那么中文会怎么样呢?

我们来试验下。

我们对中文进行编码,默认编码方式是utf8

const message = '你好呀'

const buffer = Buffer.from(message)
console.log(buffer);

我们可以看到buffer数组中有9项元素。一个中文汉字占据3个字节。 image.png

然后我们使用buffer.toString()进行解码,解码默认也是utf8

console.log(buffer.toString());

image.png 当然我们也可以在编码时指定编码方式。

const buffer = Buffer.from(message, 'utf16le')
console.log(buffer);

image.png 在解码时指定编码方式。

console.log(buffer.toString('utf16le'));

image.png 但是我们在编码时使用utf16le,解码时不指定utf16le,解码默认会使用utf8,这样最后打印的结果会是乱码。

const buffer = Buffer.from(message, 'utf16le')
console.log(buffer.toString());

image.png

方式三:通过alloc的方式创建Buffer

alloc在程序中一般表示分配内存。

const buffer = Buffer.alloc(8)
console.log(buffer);

我们发现创建了一个8位长度的buffer,里面所有的数据默认为0。

image.png 我们可以通过索引来对数组中元素进行操作。

buffer[0] = 88
buffer[1] = 0x88
console.log(buffer);

image.png

Buffer和文件读取

想要读取文件中的内容,我们可以通过fs.readFile方法。

读取文本文件

const fs = require('fs')

fs.readFile('./foo.txt', (err, data) => {
  console.log(data);
})

此时打印出来的内容是Buffer。 image.png 如果我们想要打印的是文件中的内容,可以在fs.readFile()方法中传入第二个参数指定编码方式。

fs.readFile('./foo.txt', {encoding: 'utf8'}, (err, data) => {
  console.log(data);
})

image.png 读到的东西本质上都是二进制。只不过encoding:utf8帮助我们进行了转化。当然,buffer.toString()自己来解码转换。buffer.toString()默认采用的是utf8。

fs.readFile('./foo.txt', (err, data) => {
  console.log(data.toString());
})

image.png

读取图片文件

除了文本,我们还可以读取图片。在读取文件时不能传入encoding:utf8,因为这个是对文本进行的编码。

fs.readFile('./node.webp', (err, data) => {
  console.log(data);
})

image.png 我们可以把这张图片写入到另一个文件中。

fs.readFile('./node.webp', (err, data) => {
  // console.log(data);
  fs.writeFile('./foo.png', data, err => {
    console.log(err);
  })
})

此时,我们可以看到foo.png文件是张图片。

如果想要对图片进行操作,例如裁剪旋转等,我们可以使用sharp库。

首先我们需要通过npm安装sharp库。

const sharp = require('sharp')

sharp('./foo.png')
  .resize(200, 200)
  .toFile('./foo1.png')

Buffer的创建过程

我们创建Buffer时,并不会频繁向操作系统申请内存,它会默认现申请一个8*1024字节大小的内存。