当年是看了朴灵的九浅一深 NodeJS 入门的 Node, 朴大大的书讲实践很少更多的篇幅用在了讲原理上,道理听了那么多,后来开始在前端工程领域使用 NodeJS 却处处掣肘,总结原因发现 NodeJS 中难的部分无非是文件和网络,文件操作和网络都依赖了一个很重要的对象—— Stream,这恰恰是朴大大书中没有提及的。

Buffer 朴大大在书中是有提到过的,但因为流实际上就是在处理 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 中

转载于:https://www.cnblogs.com/dolphinX/p/6279805.html

NodeJS stream 一:Buffer相关推荐

  1. nodejs stream 经典解析

    转载自:https://github.com/jabez128/stream-handbook/blob/master/README.md stream-handbook stream-handboo ...

  2. nodejs01——安装及使用、服务端及客户端、commonjs规范、fs模块的使用(文件操作及目录操作)、stream、buffer、WebServer、端口、动态资源及静态资源、头信息、请求方式

    nodejs的安装及使用 服务端及客户端 commonjs规范 fs模块的使用(文件操作及目录操作) stream buffer // Node.js介绍 Node.js 诞生于2009年,Node. ...

  3. nodeJS之二进制buffer对象

    前面的话 在ES6引入TypedArray之前,JavaScript语言没有读取或操作二进制数据流的机制.Buffer类被引入作为Nodejs的API的一部分,使其可以在TCP流和文件系统操作等场景中 ...

  4. NodeJS Stream(可读流、可写流) API解读

    原文链接:https://juejin.im/post/5ba0d504e51d450ea13223ba 流的介绍 在 NodeJS 中,我们对文件的操作需要依赖核心模块 fs,fs 中有很基本 AP ...

  5. Nodejs中的Buffer

    不记得第一次听到Buffer这个词是在什么情况下了,当时让师傅给我解释的时候,他只给了我三个词:缓冲区.二进制.读与写.用一句话形容就是,Buffer是一块可以以二进制写入和读取数据,并提供了一组方法 ...

  6. nodejs中的buffer的用法

    1.buffer的介绍 在引入 TypedArray 之前,JavaScript 语言没有用于读取或操作二进制数据流的机制. Buffer 类是作为 Node.js API 的一部分引入的,用于在 T ...

  7. Nodejs 使用 Buffer 将图片转为 base64

    一直以为图片转为 base64 很复杂,结果今天看了下 Docusaurus 的 plugin-ideal-image 插件源码,居然只要一行代码就完事了: const toBase64 = (ext ...

  8. 七天学会NodeJS

    2019独角兽企业重金招聘Python工程师标准>>> NodeJS基础 什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充 ...

  9. nodejs学习资料

    2019独角兽企业重金招聘Python工程师标准>>> NodeJS基础 什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充 ...

  10. php hex2bin nodejs,Nodejs Serialport文档翻译

    版本号:Serialport@5.0.0-beta3 本文链接 想象一个世界,你可以在那写javascript来控制搅拌机,灯,安全系统或者甚至是机器人.是的,我说的是机器人.那个世界就是这儿,现在使 ...

最新文章

  1. python 利用pyttsx3文字转语音 适用于macOS windows树莓派
  2. 网站互点排名掉了网站互点排名掉了网站互点_7天上百度首页排名优化技巧有哪些?...
  3. ZooKeeper、Eureka谁是最好的注册中心?
  4. 把列表变成列向量_线性代数的本质11 抽象向量空间
  5. python 比较运算符_Python比较运算符
  6. 六年级下计算机课ppt课件ppt课件,小学信息技术浙摄影版六年级上册第1课 走进计算机说课ppt课件...
  7. wmic冻结进程_WMIC的用法
  8. 求不大于N的最大质数
  9. 我们无法更新系统保留的分区_什么是系统保留分区,您可以删除它吗?(Windows10 科普)2020...
  10. qt超级马里奥_探索《超级马里奥》 35周年选集
  11. 2020张宇1000题【好题收集】【第四章:多元函数微分学】【第五章:二重积分】
  12. 遇人不淑之逗比程序员
  13. 一个“点赞”功能的实现代码
  14. 阿里云 Elasticsearch简介和购买流程
  15. 沟通失败是怎样造成的
  16. 【约束 约束 约束】
  17. html seo设置,搜索引擎优化中的HTML代码优化方法-如何做好SEO
  18. VSCode撸猫插件vscode-cats它来了,一起来云撸猫吧
  19. 打开IDE里XXX.rc文件夹的子项,显示“!加载失败”
  20. 网络OSI七层模型学习

热门文章

  1. 【reproject_inter】fits头文件的映射(1,改变fits文件的数据范围,2,对坐标系进行投影转换)
  2. 设置PyCharm相同词汇高亮
  3. 【C++】一次遇到的需要加入const属性的情况
  4. rabbitmq多个消费者_选型必看:RabbitMQ 七夕 Kafka,差异立现
  5. 我的 Java 血泪史
  6. 阿里云银行关键业务破冰 邢台银行首家
  7. What is a TensorFlow Session?
  8. centos 用户和组的相关命令
  9. 李洪强经典面试题32
  10. NoSQL之【MongoDB】学习(三):配置文件说明