Buffer的使用

___http://nodejs.cn/api/buffer.html

数据的二进制

___计算机中所有的内容:文字、数字、图片、音频、视频最终都会使用二进制来表示

___JavaScript可以直接去处理非常直观的数据:比如字符串,我们通常展示给用户的也是这些内容

  • 用JavaScript表示二进制是很麻烦的

  • 在网页端,图片我们一直是交给浏览器来处理的

  • JavaScript或者HTML,只是负责告诉浏览器一个图片的地址;

  • 浏览器负责获取这个图片,并且最终讲这个图片渲染出来

但是在服务器是不一样的:

  • 服务器要处理很多本地文件类型
  • 比如在Node中通过TCP建立长连接,TCP传输的是字节流,我们需要将数据转成字节再进行传入,并且需要知道传输字节的大小(客服端需要根据大小来判断读取多少内容);
  • 比如我们需要读取的是一张图片数据(二进制),再通过某些手段对图片数据进行二次的处理(裁剪、格式转换、旋转、添加滤镜),Node中有一个Sharp的库,就是读取图片或者传入图片的Buffer对其再进行处理;

Buffer和二进制

前端开发一般不处理二进制 但是在服务器端要实现一些功能 需要操作二进制数据

所以使用Node为我们提供的类 Buffer (它是全局的)

Buffer对二进制数据的存储:

  • 我们可以将Buffer看成是一个存储二进制的数组
  • 在这个数组里的每一项 保存8位二进制: 00000000
  • 每一个位置存储一个字节

8位二进制原因:

  • 计算机中将8位合在一起作为一个单元,这个单元称之为一个字节(byte);
  • 1byte = 8bit,1kb=1024byte,1M=1024kb
  • 比如TCP传输的是字节流,在写入和读取时都需要说明字节的个数
  • 比如RGB的值分别都是255,所以本质上在计算机中都是用一个字节存储的

将一个字符串放入到Buffer中:

1
2
3
4
5
6
7
8
9
const message = "hello"

//创建Buffer方式一 (过期)
// const buffer = new Buffer(message)
//console.log(buffer);

//创建Buffer方式二:
const buffer = Buffer.from(message)
console.log(buffer); //<Buffer 68 65 6c 6c 6f>
  • 如果是中文的 默认编码方式是 utf - 8

    1
    2
    3
    4
    5
    6
    7
    const message = "郝运鹏"

    const buffer = Buffer.from(message)

    console.log(buffer); //<Buffer e9 83 9d e8 bf 90 e9 b9 8f>

    console.log(buffer.toString()); //utf-8解码
    • utf-16

      1
      2
      3
      4
      5
      6
      7
      8
      9
      const message = "郝运鹏"

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

      console.log(buffer) //<Buffer dd 90 d0 8f 4f 9e>

      ////编码使用utf16le,解码uft8
      // console.log(buffer.toString()); //会有问题 默认解码是uft8
      console.log(buffer.toString('utf16le')) //需要传入 就没有问题了

其他创建方式:

Buffer的文件操作

  • 读取文本文件

    1
    2
    3
    fs.readFile('./foo.txt',{encoding:'utf-8'},(err,data)=>{
    console.log(data);
    })
  • 读取图片文件

    1
    2
    3
    4
    5
    6
    fs.readFile('./bar.JPG',(err,data)=>{
    console.log(data);
    fs.writeFile('./foo.png',data,err=>{
    console.log(err);
    })
    })
    • sharp库使用

      https://github.com/lovell/sharp

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      //sharp使用
      // sharp('./bar.JPG')
      // .resize(200,200)
      // .toFile('./baz.png')

      sharp('./foo.png')
      .resize(300,300)
      .toBuffer()
      .then( data =>{
      fs.writeFile('./bax.png',data,err=>{
      console.log(err);
      })
      })

Buffer的创建过程

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

也就是8kb

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Buffer.poolSize = 8 * 1024;
let poolSize, poolOffset, allocPool;

const encodingsMap = ObjectCreate(null);
for (let i = 0; i < encodings.length; ++i)
encodingsMap[encodings[i]] = i;

function createPool() {
poolSize = Buffer.poolSize;
allocPool = createUnsafeBuffer(poolSize).buffer;
markAsUntransferable(allocPool);
poolOffset = 0;
}
createPool();