NodeJS 难点(网络,文件)的 核心 stream 一:Buffer
文件操作和网络都依赖了一个很重要的对象—— Stream, 而这个 <node深入浅出> 没有分析的,
所以读完这本书, 在实践中还会遇到很多困难
stream 是处理 buffer
JavaScript 没有读取或者操作二进制数据流的机制。
Buffer 类作为 NodeJS API 的一部分被引入,以便能够和 TCP 等网络流和文件流等进行交互。
总而言之,Buffer 类是用来处理二进制数据,
因为太常用了,所以直接放在了全局变量里,使用的时候无需 require。
Buffer 类的实例类似于整型数组,不过缓冲区的大小在创建时确定,不能调整。
Buffer 对象不同之处在于它不经 V8 的内存分配机制,Buffer 是一个 JavaScript 和 C++ 结合的模块,内存由 C++ 申请,JavaScript 分配。
实例化 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 中
NodeJS 难点(网络,文件)的 核心 stream 一:Buffer的更多相关文章
- NodeJS 难点(网络,文件)的 核心 stream 二:stream是什么
对于大部分有后端经验的的同学来说 Stream 对象是个再合理而常见的对象,但对于前端同学 Stream 并不是那么理所当然,github 上甚至有一篇 9000 多 Star 的文章介绍到底什么是 ...
- NodeJS 难点(网络,文件)的 核心 stream 四: writable
什么是可写流 白板 可写流是对数据流向设备的抽象,用来 消费 上游流过来的数据 通过可写流程序可以把数据写入设备, 常见的是 本地磁盘文件或者 TCP.HTTP 等网络响应. 看一个之前用过的例子 ...
- NodeJS 难点(网络,文件)的 核心 stream 三:readable ?
什么是可读流 可读流 常见 读取磁盘文件.读取网络请求内容等,看一下前面介绍什么是流用的例子: const rs = fs.createReadStream(filePath); 我们常见的控 ...
- NodeJS学习笔记 (28)流操作-stream(ok)
模块概览 nodejs的核心模块,基本上都是stream的的实例,比如process.stdout.http.clientRequest. 对于大部分的nodejs开发者来说,平常并不会直接用到str ...
- 使用AVFoundation仅仅生成缩略图,不进行播放视频(本地和网络文件都可以创建视频缩略图)
使用MPMoviePlayerController来生成缩略图足够简单,但是如果仅仅是是为了生成缩略图而不进行视频播放的话,此刻使用 MPMoviePlayerController就有点大材小用了.其 ...
- 使用C#下载网络文件
下载 /// <summary> /// 下载文件 /// </summary> /// <param name="URL">下载文件地址< ...
- JAVA多线程下载网络文件
JAVA多线程下载网络文件,开启多个线程,同时下载网络文件. 源码如下:(点击下载 MultiThreadDownload.java) import java.io.InputStream; im ...
- DELPHI TDownLoadURL下载网络文件
DELPHI XE6 FMX 附件:http://files.cnblogs.com/xe2011/IDHttp_fmx.7z unit Unit1; interface uses //引用 Vc ...
- nodejs+express-实现文件上传下载管理的网站
Nodejs+Express-实现文件上传下载管理的网站 项目Github地址(对你有帮助记得给星哟):https://github.com/qcer/updo 后端:基于nodejs的express ...
随机推荐
- [Err] 1111 - Invalid use of group function
本文为博主原创,未经允许不得转载: 初衷,本想通过group by sql语句查询出不同id下总数在一定范围内的数据,所以产生如下的sql,及错误sql AND STATDATE < ' GRO ...
- codeforces 251 div2 C. Devu and Partitioning of the Array 模拟
C. Devu and Partitioning of the Array time limit per test 1 second memory limit per test 256 megabyt ...
- codevs 1081 线段树练习 2 线段树
题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第i个数是什么? 输入描述 Input Description 第一行一个正整数n,接下来n行n ...
- WPF基础学习笔记整理 (二) XAML
基础知识: XAML:Extensible Application Markup Language, zammel: 用于实例化.NET对象的标记语言: XMAL使用树形逻辑结构描述UI: BAML: ...
- webstorm注册码 永久有效!!! 前端工程师福利
2RRJMBXW33-eyJsaWNlbnNlSWQiOiIyUlJKTUJYVzMzIiwibGljZW5zZWVOYW1lIjoi5b285bK4IHNvZnR3YXJlMiIsImFzc2lnb ...
- [ios]NSThread传值 NSValue传值
NSThread:http://www.cocoachina.com/bbs/read.php?tid=51873 NSValue:http://blog.sina.com.cn/s/blog_bf9 ...
- android 管理fragment
要管理fragment们,需使用FragmentManager,要获取它,需在activity中调用方法getFragmentManager(). 你可以用FragmentManager来做以上事情: ...
- RabbitMQ入门_07_Fanout 与 Topic
A. 用广播的方式实现发布订阅 参考资料:https://www.rabbitmq.com/tutorials/tutorial-three-java.html Fanout 类型的 Exchange ...
- select exists 的应用一例
当遇到多层exists的时候,事情就变得开始复杂了.我们来看看这个例子吧 假设有三张表 选课表:学号.课程号 学生表:学号.姓名 课程表:课程号.课程名 请选出选了所有课程的学生 SELECT 姓名 ...
- 20170711筛选OutLook主题并转发
Sub 筛选OutLook主题并转发() On Error Resume Next Dim OutApp As Application Set OutApp = Application Dim Out ...