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 ...
随机推荐
- 肿瘤基因组学数据库终结者:cBioPortal---转载
转载自:http://blog.sciencenet.cn/blog-1509670-1000479.html 随着芯片和高通量测序技术的广泛应用,在肿瘤研究领域积累了越来越多的基因组学数据,特别是像 ...
- ubuntu14.04 设置开机自启动脚本
方法1.将脚本放入/etc/rc.local文件中. 方法2.添加一个ubuntu的开机启动服务 分为以下几个步骤: 1)新建一个脚本文件 new_services.sh #!/bin/bash # ...
- jquery zTree异步加载的例子
下面是使用zTree异步加载的一个例子: 1)初始化树的时候是ajax请求,返回nodes列表来初始化树的:如果一开始就异步的话,$.fn.zTree.init($("#zTree" ...
- SetParent
1.http://bbs.csdn.net/topics/390672855 该帖子中 第15楼: “ MSDN里面说了:if hWndNewParent is not NULL and the wi ...
- [ios]ios画线 使用CGContextRef,CGPath和UIBezierPath来绘画
参考 :http://www.mgenware.com/blog/?p=493 这三种东西:CGContextRef,CGPath和UIBezierPath.本质上都是一样的,都是使用Quartz来绘 ...
- 如何学好Java大数据并快速提升
Java作为一种最流行的,最热门的编程语言,可以说它无处不在,目前全球有着数十亿的设备正在运行着Java,很多服务器程序都是用Java编写,用以处理每天超过数以千万的数据.无论是手机软件.手机Java ...
- jq 插件写法
1.一次声明一个函数 $.fn.函数名 = function([options]){} $.fn.red=function(options){ var defaults = { 'color': 'r ...
- 【python】print · sys.stdout · sys.stderr
参考文档 Python重定向标准输入.标准输出和标准错误 http://blog.csdn.net/lanbing510/article/details/8487997 python重定向sys.st ...
- hdoj4283 You Are the One
题意:每个人出场时获得等待时间*值的unhappy值.有个栈换出场顺序.问怎样最小? 一开始的时候觉得在中间取断点,dp[i][j]表示区间全出场后的最小值.那么dp[i][j]=dp[i][k]+d ...
- csp 通信网络
http://blog.csdn.net/zyy_1998/article/details/78334496 试题编号: 201709-4 试题名称: 通信网络 时间限制: 1.0s 内存限制: 25 ...