Node.js之Buffer
Node.js之Buffer
什么是 Buffer
如同官方 API 中介绍的那样,在 ES6 引入 TypedArray 之前,JavaScript 没有读取或者操作二进制数据流的机制。 Buffer 类作为 NodeJS API 的一部分被引入,以便能够和 TCP 等网络流和文件流等进行交互。
现在 TypedArray 已经被添加到了 ES6 中,Buffer 类以一种更优化和适用于 NodeJS 操作的方式实现了 Unit8Array API。
总而言之,Buffer 类是用来处理二进制数据,因为太常用了,所以直接放在了全局变量里,使用的时候无需 require。
Buffer 类的实例类似于整型数组,不过缓冲区的大小在创建时确定,不能调整。Buffer 对象不同之处在于它不经 V8 的内存分配机制,Buffer 是一个 JavaScript 和 C++ 结合的模块,内存由 C++ 申请,JavaScript 分配。
关于 Buffer 内存分配相关知识不展开讨论,感兴趣同学可以看看朴老湿的书。
实例化 Buffer
在 NodeJS v6 之前都是通过调用构造函数的方式实例化 Buffer,根据参数返回不同结果。处于安全性原因,这种方式在 v6 后的版本中已经被废除,提供了
Buffer.from()
Buffer.alloc()
Buffer.allocUnsafe()
三个单独的,职责清晰的函数处理实例化 Buffer 的工作。
Buffer.from(array):返回一个内容包含所提供的字节副本的 Buffer,数组中每一项是一个表示八位字节的数字,所以值必须在 0 ~ 255 之间,否则会取模
Buffer.from(arrayBuffer):返回一个与给定的 ArrayBuffer 共享内存的新 Buffer
Buffer.from(buffer):返回给定 Buffer 的一个副本 Buffer
Buffer.from(string [, encoding]):返回一个包含给定字符串的 Buffer
Buffer.alloc(size [, fill [, encoding]]):返回指定大小并且“已填充”的 Buffer
Buffer.allocUnsafe(size):返回指定大小的 Buffer,内容必须用 buf.fill(0) 等方法填充
// 0x 表示 16 进制
Buffer.from([1, 2, 3]) // [0x1, 0x2, 0x3] Buffer.from('test', 'utf-8') // [0x74, 0x65, 0x73, 0x74] Buffer.alloc(5, 1) // [0x1, 0x1, 0x1, 0x1, 0x1] Buffer.allocUnsafe(5); // 值不确定,后面详谈
Buffer.allocUnsafe()
的执行会快于 Buffer.alloc()
看名字很不安全,确实也不安全。
当调用 Buffer.allocUnsafe()
时分配的内存段尚未初始化(不归零),这样分配内存速度很块,但分配到的内存片段可能包含旧数据。如果在使用的时候不覆盖这些旧数据就可能造成内存泄露,虽然速度快,尽量避免使用。
编码
Buffer 支持以下几种编码格式
ascii
utf8
utf16le
base64
binary
hex
Buffer 和 String 转换
字符串转为 Buffer 比较简单
Buffer.from(string [, encoding])
同时 Buffer 实例也有 toString 方法将 Buffer 转为字符串
buf.toString([encoding[, start[, end]]])
Buffer 拼接
使用 concat 方法可以讲多个 Buffer 实例拼接为一个 Buffer 实例
Buffer.concat(list[, totalLength])
StringDecoder
在 NodeJS 中一个汉字由三个字节表示,如果我们处理中文字符的时候使用了不是3的倍数的字节数就会造成字符拼接乱码问题。
const buf = Buffer.from('中文字符串!'); for(let i = 0; i < buf.length; i+=5){ var b = Buffer.allocUnsafe(5); buf.copy(b, 0, i); console.log(b.toString()); }
这样可以看到结果中出现了乱码
但如果使用 string_decoder 模块便可以解决这个问题
const StringDecoder = require('string_decoder').StringDecoder; const decoder = new StringDecoder('utf8'); const buf = Buffer.from('中文字符串!'); for(let i = 0; i < buf.length; i+=5){ var b = Buffer.allocUnsafe(5); buf.copy(b, 0, i); console.log(decoder.write(b)); }
StringDecoder 在得到编码后,知道宽字节在utf-8下占3个字节,所以在处理末尾不全的字节时,会保留到第二次 write()。目前只能处理UTF-8、Base64 和 UCS-2/UTF-16LE。
Buffer 其它常用 API
还有一些 Buffer 常用的 API
Buffer.isBuffer:判断对象是否为 Buffer
Buffer.isEncoding:判断 Buffer 对象编码
buf.length:返回 内存为此 Buffer 实例所申请的字节数,并不是 Buffer 实例内容的字节数
buf.indexOf:和数组的 indexOf 类似,返回某字符串、acsii 码或者 buf 在改 buf 中的位置
buf.copy:将一个 buf 的(部分)内容复制到另外一个 buf 中

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
正则表达式下——相关方法
JavaScript正则表达式下——相关方法 上篇博客JavaScript 正则表达式上——基本语法介绍了JavaScript正则表达式的语法,有了这些基本知识,可以看看正则表达式在JavaScript的应用了,在一切开始之前,看看RegExp实例的几个属性 RegExp实例对象有五个属性 global:是否全局搜索,默认是false ignoreCase:是否大小写敏感,默认是false multiline:多行搜索,默认值是false lastIndex:是当前表达式模式首次匹配内容中最后一个字符的下一个位置,每次正则表达式成功匹配时,lastIndex属性值都会随之改变。 source:正则表达式的文本字符串除了将正则表达式编译为内部格式从而使执行更快的compile()方法,对象还有两个我们常用的方法 regObj.test(strObj) 方法用于测试字符串参数中是否存正则表达式模式,如果存在则返回true,否则返回false var reg=/\d+\.\d{1,2}$/g; reg.test('123.45'); //true reg.test('0.2'); //tru...
- 下一篇
双亲委派模型
类加载流程 类加载流程,先加载Bootstrap ClassLoader 启动类加载即最顶层的加载类。这部分由C++ 编写。继续再次加载Extention ClassLoader 扩展类加载器由Bootstrap ClassLoader加载,加载进入内存。继续再次加载Application ClassLoader 应用类加载器,即系统即在此,加载当前应用下的类最后再次加载ClassLoader类 双亲委派模型 该模型是先检查指定名称的类是否已经加载过,如果加载进入内存,不加载直接返回,如果没有加载过,判断是否有父类加载器,如果拥有父类加载器,那么将会直接将权利移交给父类,由父类代理当前类进行加载该类。或者是调用C++的bootstrap类加载器来加载该类最后如果三者都没有找到类,那么直接调用当前类加载器的findClass方法来完成类加载。即,如果需要需要加载自定义的类,那么就需要重写findClass方法。 即,如果需要将当前类加载进入,那么就需要重写findClass方法,若未找到这几种类,则会自动调用findClass方法。 调用过程 先加载父类,若父类未加载,继续调用父类,直到...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Hadoop3单机部署,实现最简伪集群
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池