一次搞定Node中的Buffer

一.写在前面


大家好,我是一溪风月一名前端程序员,目前在逐步走向全栈的道路,我们知道计算机中的内容无论是文字,图片,音频,视频本质上都是以二进制的形式来表示的,JavaScript可以非常直接的去处理非常直观的数据,比如字符串,我们通常展示给用户的也是这些内容,事实上在网页端,图片我们一直是交给浏览器来处理的,JS或者HTML只是负责告诉浏览器的一个图片的地址,浏览器负责获取这个图片,并最终将这个图片渲染出来,但是对于服务器来说是不一样的,在我们学习Node之后我们必须要学习这些内容,相对于前端,服务器要处理的本地文件的类型相对较多,比如某一个保存文本并不是使用utf-8进行编码的而是使用GBK,那么我们必须读取到他们的二进制数据,再通过GBK转换成相应的文字,比如我们需要读取的是一张图片数据(二进制),再通过某些手段对图片数据进行二次处理(剪裁,格式转换,旋转,添加滤镜)Node中有有一个Sharp库就是读取图片或者传入图片的Buffer对其再进行处理,比如在Node中通过建立TCP建立长连接,TCP传输的字节流,我们需要将数据转换成字节再进行传入,并且需要知道传输的字节的大小(客户端需要根据大小来判断读取多少内容)这篇文章我们就来讲解一下和服务器数据处理相关的概念Buffer,如果你觉得这篇文章对你有帮助不要吝啬你的👍如果你想了解更多相关的内容可以关注我的专栏Node服务端和我一起学习,一起进步~

二.Buffer和二进制


通过上述的内容我们了解到对文件的处理其实处理的是二进制,但是我们直接处理二进制其实是非常麻烦的,所以在Node中为我们提供了一个类(事实上在其他语言中也是这样做的)这个类就是Buffer并且它是全局的,我们可以将Buffer看作一个存储二进制的数组,这个数组的每一项可以存储8位二进制,其实就是一个字节,为什么是8位哪?

因为在计算机中很少的情况我们会直接操作一位二进制,因为一位二进制存储的数据非常有限的,所以通常会将8位合在一起作为一个单元,这个单元叫做字节(byte)也就是说1byte = 8bit 1kb = 1024byte1M = 1024kb比如很多编程语言中的int类型是4个字节,long类型时8个字节,比如TCP传输的是字节流,在写入和读取时都需要说明字节的个数,比如RGB的值都是255,所以本质上在计算机中都是使用一个字节存储的。

三.Buffer和字符串之间的转换


我们可以直接通过Buffer类来将字符串转换为buffer。

js 复制代码
const buf = new Buffer("Hello")
console.log(buf)

但是其实在Node中并不希望我们通过这种方式来使用,我们可以通过类方法来创建使用。

js 复制代码
const buf = Buffer.from("world")
console.log(buf)
// <Buffer 77 6f 72 6c 64>

💡如果你传入的是英文的话,在<Buffer 77 6f 72 6c 64>其实每一位就代表这一个英文字母的十六进制,但是如果是中文的情况下,可能使用一个字节不足以表示,可能需要3个字节才能表示一个中文汉字。

在Node中将字符串转为Buffer会经历如下的过程

js 复制代码
const buf = Buffer.from("why")
console.log(buf)
// <Buffer 77 68 79>

如果你通过上述的from方法将字符串转换为Buffer你需要将它再转换回来的时候就需要使用toString()

但是需要注意的是编码问题,一版情况下我们使用的都是utf8的编码,编码和解码使用的方式要保持一致,否则会出现乱码的问题。

js 复制代码
const buf = Buffer.from("why","utf8")
console.log(buf)
console.log(buf.toString("utf8"))

四.Buffer的其他创建与操作


  1. 使用Buffer.alloc(size)创建固定大小的buffer
js 复制代码
const buf = Buffer.alloc(8)
buf[0] = 100
buf[1] = 0x66
console.log(buf)
console.log(buf.toString())
buf[2] = 'm'.charCodeAt()
console.log(buf)
  1. 从文件读取Buffer进行操作
js 复制代码
const fs = require("fs")
fs.readFile("./test.txt", (err, data) => {
  console.log(data.toString())
  // 对读取到的buffer进行操作
})

💡当我们对一个图片进行处理的时候我们就可以借助Sharp进行图片的处理,然后这个库会输出给我们一个新的Buffer,然后我们再将这个图片进行写入。

  1. 当然Buffer的API有很多我们可以先学习比较核心的内容,当我们遇到使用Buffer的场景再进行对应的查询。

五.Buffer的创建过程


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

六.Buffer.from源码


假如我们调用Buffer.from来申请buffer我们以创建字符串为例,以下是它的实现。

我们可以看到在使用Buffer.from的时候调用了fromString这个方法,以下是fromString的实现

接着我们查看fromStringFast:这里做的事情是判断剩余的长度是否还足够填充这个字符串,如果不足够,那么就要通过createPool创建新的空间,如果够就直接使用,但是之后要进行poolOffset的偏移变化。

七.总结


这篇文章到这里基本就结束了🎉,这篇文章我们主要学习Buffer的概念和计算机中存储的内容的表示方式,我们具体的学习了Buffer的常用API,在Buffer中API有很多,我们只需要记忆常用的即可,当遇到需要使用Buffer的时候可以根据具体需求去查询,在文章的最后我们简单的查看了一下Buffer创建的源码分析,了解即可,Buffer在我们对文件和图片的处理时候会使用的比较多。

相关推荐
过期的H2O214 分钟前
【H2O2|全栈】关于CSS(4)CSS基础(四)
前端·css
纳尼亚awsl28 分钟前
无限滚动组件封装(vue+vant)
前端·javascript·vue.js
八了个戒33 分钟前
【TypeScript入坑】TypeScript 的复杂类型「Interface 接口、class类、Enum枚举、Generics泛型、类型断言」
开发语言·前端·javascript·面试·typescript
西瓜本瓜@35 分钟前
React + React Image支持图像的各种转换,如圆形、模糊等效果吗?
前端·react.js·前端框架
黄毛火烧雪下36 分钟前
React 的 useEffect 钩子,执行一些异步操作来加载基本信息
前端·chrome·react.js
蓝莓味柯基41 分钟前
React——点击事件函数调用问题
前端·javascript·react.js
资深前端之路42 分钟前
react jsx
前端·react.js·前端框架
cc蒲公英1 小时前
vue2中使用vue-office库预览pdf /docx/excel文件
前端·vue.js
Sam90291 小时前
【Webpack--013】SourceMap源码映射设置
前端·webpack·node.js
小兔崽子去哪了1 小时前
Element plus 图片手动上传与回显
前端·javascript·vue.js