nodejs第四天(Buffer)

1,033 阅读4分钟

The Buffer class was introduced as part of the Node.js API to make it possible to interact with octet streams in the context of things like TCP streams and file system operations.

  通过文档里的介绍很显然我们可以知道Buffer是用来干什么的了,这是用来处理二进制数据的,在网络和文件中是最为常见的了。

一、Buffer对象

  其实你第一眼看到buffer,你就会觉得这是个很像数组的东西,Buffer的实例对象就是一个类似数组的东西,但是大小是固定的,你分配多少就是多少,而且Buffer是在V8堆外分配物理内存的,是由C++层面实现内存的申请的。
  好了,我们来看一个Buffer的实例:

  我们可以看到这个buffer实例的样子,还有一点,针对于不同的编码的字符串,它所占用的buffer长度就不一样,比如所在utf-8下,中文是3、字母和半角标点是1

  那么创建一个Buffer实例有哪些方法呢?

// 创建Buffer实例的方法

//  1. new Buffer(),参数传入长度,每个buffer元素用0填充,但是官方已经废弃,建议使用下面的
const buf1 = new Buffer(10);
console.log(buf1);

//  2. Buffer.alloc(),可以传入两个参数,第一个是Buffer的长度,第二个是Buffer填充的值,如果不传入第二个参数就全部0填充
const buf2 = Buffer.alloc(10, 1);
console.log( buf2 );

//  3. Buffer.allocUnsafe(),具有明显的性能优势,因为不需要给里面的元素重写,但是里面可能包含一些旧数据、敏感数据,所以说不安全
const buf3 = Buffer.allocUnsafe(10);
console.log( buf3 );

//  4. Buffer.from(),这里面能够传入的参数有几种

//  string
const buf4 = Buffer.from('node');
console.log(buf4 );

//  array
const buf5 = Buffer.from([1, 2, 3]);
console.log( buf5 );

//  buffer, 将buffer中的数据拷贝到一个新的buffer中
const buf6 = Buffer.from(buf5);
console.log( buf6 );

//  当然了,还有一种arrayBuffer的,这里就不介绍了

  可以看一下上面这些创建的输出:

二、 Buffer的一些方法

  方法里面就介绍几个常用的的方法。

1. Buffer的方法

- Buffer.isBuffer()

  顾名思义,一眼就知道这个方法是用来干什么的,判断是否是一个Buffer的。

- Buffer.byteLength()

  这个方法是用来返回buffer的长度的,和数组的length差不多。

- Buffer.concat()

  这个方法的作用是将几个buffer合并到一起,组成一个新的buffer。

2. Buffer实例的方法

- buf.entries()

  其实看了这么多方法,我们可以发现,基本上对于数组或者是类数组,对象的一些方法,在buffer中都能找到,并且作用是差不多的,所以说在你使用buffer的时候,有你觉得应该有的方法就尽管去查吧。

- buf.length

  这个其实大家也清楚,是返回buffer长度的。

- buf.toString()

  这个方法就和Object的toString作用是差不多的。


  下面呢,介绍一个东西,StringDecoder,这东西是我在学习的时候从一些博客上和书上发现的,这个东西来自于string_decoder模块,我们用代码来看一下这个对象,很强大。在深入浅出上也有对应的例子。

// 我们都知道在UTF8下,中文字符长度为3,那么我们打印5个会发生什么情况呢?
const buf = Buffer.from('这是美妙的一天');
const buf1 = Buffer.alloc(5);
buf.copy(buf1, 0, 0, 5);

console.log(buf1.toString());  //  这�,我们可以看到乱码了,因为剩下的两个字节转换不成汉字

// 我们试一试另外一种方法
const StringDecoder = require('string_decoder').StringDecoder;
const decoder = new StringDecoder('utf8');

const buf = Buffer.from('这是美妙的一天');
const buf1 = Buffer.alloc(10);
const buf2 = Buffer.alloc(11);
buf.copy(buf1, 0, 0, 10);
buf.copy(buf2, 0, 10, 21);


console.log(decoder.write(buf1));  // 这是美
console.log(decoder.write(buf2));  // 妙的一天

  可以看到,很神奇,中文转码并没有分开进行解码,美妙两个字是分开进行的解码,StringDecoder在得到编码之后知道utf8的宽字符是以3个字节的方式进行存储,所以第一次只解码了9个,剩余的一个保留在内部,第二次组合起来再进行解码。


  关于buffer不只是这么一点,buffer在我们开发过程中也是很常见的,不然也不会放到全局中,这东西很重要,还需要继续学习加强,谢谢大家。

PS: 关于tmux的使用,我觉得用一片文章来安利一下都可以,很便捷,哈哈。