javascript的一个不足之处是不能处理二进制数据,于是node中引入了Buffer类型。这个类型以一个字节(即8位)为单位,给数据分配存储空间。它的使用类似于Array,但是与Array又有不同:Buffer在定义的时候必须明确知道其长度,但是Array的长度是可以动态变化的。定义Buffer有三种方式:

1. var buf = new Buffer(3);//指定buffer占用3个字节

2. var buf = new Buffer("hello","utf-8");//指定了字符串,以及字符串的编码类型为utf-8,占用5个字节

3. var buf = new Buffer([256,255,2]);//定义了buffer的每个字节所存储的数字,最大为255,超过255取模

为什么介绍Buffer呢?因为本文所介绍的流就是以字节为单位传输的,而Buffer存储的就是字节。

Node中用fs模块的createReadStream和createWriteStream分别创建可读流和可写流。先介绍第一个接口。

一. createReadStream

这个方法继承了events类,因而也可以发射和监听相关事件。其用法如下:

var rs = fs.createReadStream(filePath , {options});
rs.on("data",function(data){
console.log(data);
});
rs.on("end",function(data){
console.log("resource file is completely read");
});
rs.on("error",function(err){
console.log("something is wrong during processing");
})

options是一组key-value值,常用的设置如下:

flags: 对文件进行何种操作,默认为'r',读文件

encoding:指定编码,默认为null,如果不设置具体的编码格式,读出的数据就是Buffer类型;也可以使用rs.setEncoding("utf-8")指定编码格式

start:从start开始读取文件

end:读取文件到end为止(包括end)

highWaterMark:最高水位线,内部缓冲区最多能容纳的字节数,如果超过这个大小,就停止读取资源文件,默认值是64KB

前面几个设置就遵从字面意思,比较好理解。重点讲讲highWaterMark。

比如有一个100KB的文件,设置highWaterMark为10KB,那么系统会先从资源文件中读取出10KB的数据,再触发data事件;然后再读取10KB的数据,触发data事件,不断执行,直到读出了所有的数据,触发end事件。highWaterMark不能设置的过小,过小就会频繁的操作文件,影响性能。

可读流还有两个重要的方法:pause和resume,分别可以禁止发射data事件以及激活发射data事件。这两个方法稍后再讲解。

二.createWriteStream

和createReadStream一样,它也是events的一个子类。它的drain事件在缓冲区数据写入完毕后被触发。

其用法举例:

var ws = fs.createWriteStream(filePath, {options});

其常用的options值为:

flags:对文件进行何种操作,默认为“w",代表写文件;如果是"a",代表每次写入的时候,不清空文件中的原有数据,而是直接在原有数据的末尾添加新数据

encoding:指定写入的编码格式,默认为null

start:文件开始写入的位置

highWaterMark:缓存区能够容纳的最大字节数,默认为16KB,如果超过这个值,write方法就会返回false

可写流的highWaterMark也代表了缓冲区的容量,如果缓冲区已经装满了,继续写入数据就会失败。只有等缓冲区里的内容被写入文件后,才可以重新调用write方法写入下一个highWaterMark大小的数据(data chunk)。

可写流也有两个重要的方法:write和end,write定义了写入的内容,end可以将还未写入的内容强行写入文件,并且关闭目标文件(不能继续写入了)。

基于以上分析,我们来实现一个文件拷贝的例子:

var fs=require("fs");
var rs = fs.createReadStream("./Koala.jpg");//默认64KB
var ws = fs.createWriteStream("./Copy.jpg");//默认16KB,写入速度小于读取速度
rs.on("data",function(data){
var flag = ws.write(data);
if (!flag){ //缓冲区已满
rs.pause();//停止触发data事件
}
});
ws.on("drain",function(){
rs.resume();//如果当前的缓冲区写入完毕,就重新触发data事件
});
rs.on("end",function(){
ws.end();//将剩下的数据全部写入,并且关闭写入的文件
})

这个例子综合运用了可读流和可写流的事件和重要方法。由于读流比写入流的速度快,所以要控制可读流的数据流动。通过控制data事件的触发时机,就解决读写速度不匹配的问题。

node中的可读流和可写流的更多相关文章

  1. node.js中stream流中可读流和可写流的使用

    node.js中的流 stream 是处理流式数据的抽象接口.node.js 提供了很多流对象,像http中的request和response,和 process.stdout 都是流的实例. 流可以 ...

  2. node中可读流、可写流

    javascript的一个不足之处是不能处理二进制数据,于是node中引入了Buffer类型.这个类型以一个字节(即8位)为单位,给数据分配存储空间.它的使用类似于Array,但是与Array又有不同 ...

  3. python中使用xlrd读excel使用xlwt写excel

    原文地址 :http://www.bugingcode.com/blog/python_xlrd_read_excel_xlwt_write_excel.html 在数据分析和运营的过程中,有非常多的 ...

  4. 极简 Node.js 入门 - 4.4 可写流

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  5. Node 中的 stream (流)

    流的概念 流(stream)在 Node.js 中是处理流数据的抽象接口(abstract interface). stream 模块提供了基础的 API .使用这些 API 可以很容易地来构建实现流 ...

  6. node中的stream(流)内置模块

    stream是Node.js提供的又一个仅在服务区端可用的模块,目的是支持“流”这种数据结构. 什么是流?流是一种抽象的数据结构.想象水流,当在水管中流动时,就可以从某个地方(例如自来水厂)源源不断地 ...

  7. node中的Stream-Readable和Writeable解读

    在node中,只要涉及到文件IO的场景一般都会涉及到一个类-Stream.Stream是对IO设备的抽象表示,其在JAVA中也有涉及,主要体现在四个类-InputStream.Reader.Outpu ...

  8. Node中的http模块

    通过Node模块,我们可以实现客户端和服务器端.这篇文章主要研究如何利用http和一些相关模块构建客户端和服务器端代码.读完本文,将能够实现client向server发送数据,而server将数据原样 ...

  9. Node中的net模块提供的前端通信

    Node中的net模块提供的前端通信 客户端 业务: 客户端现在要在终端输入内容,然后回车发送内容给服务器 解决: Node中提供了一个叫做 readline 的 模块用于读取命令行内容 [ 单行读取 ...

随机推荐

  1. linux之log_format

    log_format是指存储日志的时候所采用的格式,可以在/usr/local/nginx/conf/nginx.conf的http字段中设置 下面是一个典型的log_format设置 log_for ...

  2. mysql登陆出现unknown database错误可能原因

    输入了错误命令如 # mysql -u root -p test 然后客户端会出现需要输入命令的提示,即使输入正确出现错误提示 正确命令是 # mysql -u root -p

  3. UNICODE与UTF8和GBK之间的关系

    http://wenku.baidu.com/link?url=bheGEzfSjEx-QX-ciME5oKooKYE08_NJZ02l2kKFa7kVZJ4t8Ks2uSNByovgP2QL6btq ...

  4. PageRank与TrustRank影响因素分析

    PageRank(PR)里的page不是指网页,而是指Google创始人拉里?佩奇(Larry Page),是他在2001年申请的专利中以自己名字命名的,Google的PageRank根据网站的外部链 ...

  5. php分10个不同等级压缩优化图片

    今天找到一个php写的压缩图片程序,可以分10个等级(0-9)来压缩,0等级时压缩比率不是很大,图片不会失真:随着压缩等级不断增大,图片会变得越来越不清晰,通常压缩后图片大小可以减少到原来的50%,压 ...

  6. 三线程连续打印ABC

    package test5; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Reentr ...

  7. 查看并更改mysql编码

    show variables like 'character%'; set character_set_client=utf8 ; set character_set_connection=utf8 ...

  8. 用Visual Studio调试Windows和驱动程序

    由于本人能力有限,翻译不足之处敬请谅解,欢迎批评指正:sunylat@163.com Visual Studio版本:Visual Studio 2015企业版,中文环境. MSDN原文:https: ...

  9. repeat语句

    一.repeat语句格式repeat语句用于"重复执行循环体,直到指定的条件为真时为止" repeat语句格式:repeat  语句1;  语句2;  --  语句n;until ...

  10. PHP连接SQLServer

    连接前配置系统: 1.检查文件 php5.2.5/ntwdblib.dll 默认下面有一个,不能连接再替换. 下载正确版本的 ntwdblib.dll (2000.80.194.0),地址: http ...