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. [solr] - IKAnalyzer 分词加入

    1.下载IK Analyzer中文分词器:http://ik-analyzer.googlecode.com/files/IK%20Analyzer%202012FF_hf1.zip 2.解压出zip ...

  2. Openstack Neutron L2 Population

    Why do we need it, whatever it is? VM unicast, multicast and broadcast traffic flow is detailed in m ...

  3. 将WeX5部署到自己的Tomcat服务器上

    页面服务UIServer布署 WeX5自带页面服务UIServer的是标准Web应用,可以部署在Java Web应用服务器上.下面介绍如何在Tomcat和WebLogic中部署WeX5的UIServe ...

  4. 【freemaker】之获取xml的值

    测试代码 @Test public void test09() throws Exception{ root.put("doc", NodeModel.parse(new Inpu ...

  5. Visual.Studio.2013.IDE+visual.studio.15.preview5 编译器

    硬盘版Visual.Studio.2013.IDE + visual.studio.15.preview5 编译器 使用前注意以下事项: 1.右键-管理员权限安装,VS15补丁.exe,补丁是VS15 ...

  6. Hadoop on Yarn 各组件详细原理

    运行在独立的节点上的ResourceManager和NodeManager一起组成了yarn的核心,构建了整个平台.ApplicationMaster和相应的container一起组成了一个Yarn的 ...

  7. Yii里表单的操作方法(展示渲染待续......)

    <?php$form=\yii\widgets\ActiveForm::begin(['action'=>\yii\helpers\Url::to('name/create')]);ech ...

  8. search-a-2d-matrix(二维矩阵查找)

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  9. LeetCode Implement pow(x, n).

    这个题目我也没有思路,同学们可以查看这个http://www.cnblogs.com/NickyYe/p/4442867.html 下面是我改进后的代码 第一种方法: class Solution { ...

  10. 【练习】数据移动---parfile导出表中指定行:

    要求: ①创建存放数据的文件: ②使用默认的bad文件生成方式: ③使用truncate选项方式. 1.准备条件: [oracle@host03 ~]$ mkdir datadump [oracle@ ...