Node.js中的缓冲与流模块详细介绍


Posted in Javascript onFebruary 11, 2015

缓冲(buffer)模块

js起初就是为浏览器而设计的,所以能很好的处理unicode编码的字符串,但不能很好的处理二进制数据。这是Node.js的一个问题,因为Node.js旨在网络上发送和接收经常是以二进制格式传输的数据。比如:

 - 通过TCP连接发送和接收数据;
 - 从图像或者压缩文件读取二进制数据;
 - 从文件系统读写数据;
 - 处理来自网络的二进制数据流

而Buffer模块为Node.js带来了一种存储原始数据的方法,于是可以再js的上下文中使用二进制数据。每当需要在Node.js中处理I/O操作中移动的数据时,就有可能使用Buffer模块。

类:Buffer

Buffer 类是一个全局变量类型,用来直接处理2进制数据的。 它能够使用多种方式构建。

原始数据保存在 Buffer 类的实例中。一个 Buffer 实例类似于一个整数数组

1.new Buffer(size):分配一个新的 buffer 大小是 size 的8位字节.
2.new Buffer(array):分配一个新的 buffer 使用一个8位字节 array 数组.
3.new Buffer(str, [encoding]):encoding String类型 - 使用什么编码方式,参数可选.

4.类方法: Buffer.isEncoding(encoding):如果给定的编码 encoding 是有效的,返回 true,否则返回 false。
5.类方法: Buffer.isBuffer(obj):测试这个 obj 是否是一个 Buffer. 返回Boolean
6.类方法: Buffer.concat(list, [totalLength]):list {Array}数组类型,Buffer数组,用于被连接。totalLength {Number}类型 上述Buffer数组的所有Buffer的总大小。
除了可以读取文件得到Buffer的实例外,还能够直接构造,例如:

var bin = new Buffer([ 0x48, 0x65, 0x6c, 0x6c, 0x6c ]);

Buffer与字符串类似,除了可以用.length属性得到字节长度外,还可以用[index]方式读取指定位置的字节,例如:

bin[0]; // => 0x48;

Buffer与字符串能够互相转化,例如可以使用指定编码将二进制数据转化为字符串:
var str = bin.toString('utf-8'); // => "hello"

.slice方法不是返回一个新的Buffer,而更像是返回了指向原Buffer中间的某个位置的指针,如下所示。
1.[ 0x48, 0x65, 0x6c, 0x6c, 0x6c ]

2.    ^           ^

3.    |           |

4.   bin     bin.slice(2)

写入缓冲区

var buffer = new Buffer(8);//创建一个分配了8个字节内存的缓冲区

console.log(buffer.write('a','utf8'));//输出1

这会将字符"a"写入缓冲区,node返回经过编码以后写入缓冲区的字节数量,这里的字母a的utf-8编码占用1个字节。

复制缓冲区

Node.js提供了一个将Buffer对象整体内容复制到另一个Buffer对象中的方法。我们只能在已经存在的Buffer对象之间复制,所以必须创建它们。

buffer.copy(bufferToCopyTo)

其中,bufferToCopyTo是要复制的目标Buffer对象。如下示例:

var buffer1 = new Buffer(8);

buffer1.write('nice to meet u','utf8');

var buffer2 = new Buffer(8);

buffer1.copy(buffer2);

console.log(buffer2.toString());//nice to meet u

流模块

在UNIX类型的操作系统中,流是个标准的概念。有如下三个主要的流:

1.标准输入
2.标准输出
3.标准错误

可读流

如果说,缓冲区是Node.js处理原始数据的方式的话,那么流通常是Node.js移动数据的方式。Node.js中的流是可读的或者可写的。Node.js中许多模块都使用了流,包括HTTP和文件系统。

假设我们创建一个classmates.txt的文件,并从中读入姓名清单,以便使用这些数据。由于数据是流,这就意味着完成文件读取之前,从收到最初几个字节开始,就可以对数据动作,这是Node.js中的一个常见模式:

var fs = require('fs');

var stream = fs.ReadStream('classmates.txt');

stream.setEncoding('utf8');

stream.on('data', function (chunk) {

    console.log('read some data')

});

stream.on('close', function () {

    console.log('all the data is read')

});

在以上示例中,在收到新数据时触发事件数据。当文件读取完成后触发关闭事件。

可写流

显然,我们也可以创建可写流以便写数据。这意味着,只要一段简单的脚本,就可以使用流读入文件然后写入另一个文件:

var fs = require('fs');

var readableStream = fs.ReadStream('classmates.txt');

var writableStream = fs.writeStream('names.txt');

readableStream.setEncoding('utf8');

readableStream.on('data', function (chunk) {

    writableStream.write(chunk);

});

readableStream.on('close', function () {

    writableStream.end();

});

现在,当接收到数据事件时,数据会被写入可写流中。

readable.setEncoding(encoding):返回: this

readable.resume():同上。该方法让可读流继续触发 data 事件。

readable.pause():同上。该方法会使一个处于流动模式的流停止触发 data 事件,切换到非流动模式,并让后续可用数据留在内部缓冲区中。
类: stream.Writable

Writable(可写)流接口是对您正在写入数据至一个目标的抽象。

1.writable.write(chunk, [encoding], [callback]):

chunk {String | Buffer} 要写入的数据
encoding {String} 编码,假如 chunk 是一个字符串
callback {Function} 数据块写入后的回调
返回: {Boolean} 如果数据已被全部处理则 true。

该方法向底层系统写入数据,并在数据被处理完毕后调用所给的回调。

2.writable.cork():强行滞留所有写入。

滞留的数据会在 .uncork() 或 .end() 调用时被写入。

3.writable.end([chunk], [encoding], [callback])

chunk {String | Buffer} 可选,要写入的数据
encoding {String} 编码,假如 chunk 是一个字符串
callback {Function} 可选,流结束后的回调
在调用 end() 后调用 write() 会产生错误。

// 写入 'hello, ' 然后以 'world!' 结束

http.createServer(function (req, res) {

  res.write('hello, ');

  res.end('world!');

  // 现在不允许继续写入了

});
Javascript 相关文章推荐
Highslide.js是一款基于js实现的网页中图片展示插件
Mar 30 Javascript
Extjs在exlipse中设置自动提示的方法
Apr 07 Javascript
防止xss和sql注入:JS特殊字符过滤正则
Apr 18 Javascript
js 判断图片是否加载完以及实现图片的预下载
Aug 14 Javascript
JS+CSS实现自动切换的网页滑动门菜单效果代码
Sep 14 Javascript
jQuery多级手风琴菜单实例讲解
Oct 22 Javascript
jQuery validate 验证radio实例
Mar 01 Javascript
微信小程序实现瀑布流布局与无限加载的方法详解
May 12 Javascript
react native仿微信PopupWindow效果的实例代码
Aug 07 Javascript
基于vue中解决v-for使用报红并出现警告的问题
Mar 03 Javascript
vue.js引入外部CSS样式和外部JS文件的方法
Jan 06 Javascript
JS桶排序的简单理解与实现方法示例
Nov 25 Javascript
javascript中var的重要性分析
Feb 11 #Javascript
JavaScript设计模式之工厂模式和构造器模式
Feb 11 #Javascript
js实现可兼容IE、FF、Chrome、Opera及Safari的音乐播放器
Feb 11 #Javascript
45个JavaScript编程注意事项、技巧大全
Feb 11 #Javascript
JS实现判断碰撞的方法
Feb 11 #Javascript
javascript异步编程代码书写规范Promise学习笔记
Feb 11 #Javascript
jquery实现动态操作select选中
Feb 11 #Javascript
You might like
php中time()和mktime()方法的区别
2013/09/28 PHP
PHP实现的memcache环形队列类实例
2015/07/28 PHP
php+mysql实现简单登录注册修改密码网页
2016/11/30 PHP
laravel实现分页样式替换示例代码(增加首、尾页)
2017/09/22 PHP
windows系统php环境安装swoole具体步骤
2021/03/04 PHP
JQuery 遮罩层实现(mask)实现代码
2010/01/09 Javascript
javascript中字符串拼接需注意的问题
2010/07/13 Javascript
jquery.cvtooltip.js 基于jquery的气泡提示插件
2010/11/19 Javascript
用JS判断IE版本的代码 超管用!
2011/08/09 Javascript
JavaScript获取页面上被选中文字的方法技巧
2015/03/13 Javascript
JavaScript基于setTimeout实现计数的方法
2015/05/08 Javascript
使用PBFunc在Powerbuilder中支付宝当面付款功能
2016/10/01 Javascript
ajax与jsonp的区别及用法
2018/10/16 Javascript
微信小程序实现星星评价效果
2018/11/02 Javascript
vue从一个页面跳转到另一个页面并携带参数的解决方法
2019/08/12 Javascript
jquery实现有过渡效果的tab切换
2020/07/17 jQuery
python检测远程服务器tcp端口的方法
2015/03/14 Python
Python中的字符串替换操作示例
2016/06/27 Python
Python中关于Sequence切片的下标问题详解
2017/06/15 Python
python实现各进制转换的总结大全
2017/06/18 Python
Windows下python3安装tkinter的问题及解决方法
2020/01/06 Python
Python编程快速上手——强口令检测算法案例分析
2020/02/29 Python
为什么说python适合写爬虫
2020/06/11 Python
解决pip安装的第三方包在PyCharm无法导入的问题
2020/10/15 Python
Python实现简单的猜单词小游戏
2020/10/28 Python
html5理解head_动力节点Java学院整理
2017/07/13 HTML / CSS
html5的画布canvas——画出简单的矩形、三角形实例代码
2013/06/09 HTML / CSS
不同浏览器创建XMLHttpRequest方法有什么不同
2014/11/17 面试题
语文教育专业应届生求职信
2013/11/23 职场文书
测控技术与仪器个人求职信范文
2013/12/30 职场文书
护士毕业生自荐信
2014/02/07 职场文书
2014年十一国庆节活动方案
2014/09/16 职场文书
领导干部群众路线对照检查材料
2014/11/05 职场文书
2015年仓库管理员工作总结
2015/04/21 职场文书
芙蓉镇观后感
2015/06/10 职场文书
PHP 技巧 * SVG 保存为图片(分享图生成)
2021/04/02 PHP