node中的可读流和可写流
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中的可读流和可写流的更多相关文章
- node.js中stream流中可读流和可写流的使用
node.js中的流 stream 是处理流式数据的抽象接口.node.js 提供了很多流对象,像http中的request和response,和 process.stdout 都是流的实例. 流可以 ...
- node中可读流、可写流
javascript的一个不足之处是不能处理二进制数据,于是node中引入了Buffer类型.这个类型以一个字节(即8位)为单位,给数据分配存储空间.它的使用类似于Array,但是与Array又有不同 ...
- python中使用xlrd读excel使用xlwt写excel
原文地址 :http://www.bugingcode.com/blog/python_xlrd_read_excel_xlwt_write_excel.html 在数据分析和运营的过程中,有非常多的 ...
- 极简 Node.js 入门 - 4.4 可写流
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- Node 中的 stream (流)
流的概念 流(stream)在 Node.js 中是处理流数据的抽象接口(abstract interface). stream 模块提供了基础的 API .使用这些 API 可以很容易地来构建实现流 ...
- node中的stream(流)内置模块
stream是Node.js提供的又一个仅在服务区端可用的模块,目的是支持“流”这种数据结构. 什么是流?流是一种抽象的数据结构.想象水流,当在水管中流动时,就可以从某个地方(例如自来水厂)源源不断地 ...
- node中的Stream-Readable和Writeable解读
在node中,只要涉及到文件IO的场景一般都会涉及到一个类-Stream.Stream是对IO设备的抽象表示,其在JAVA中也有涉及,主要体现在四个类-InputStream.Reader.Outpu ...
- Node中的http模块
通过Node模块,我们可以实现客户端和服务器端.这篇文章主要研究如何利用http和一些相关模块构建客户端和服务器端代码.读完本文,将能够实现client向server发送数据,而server将数据原样 ...
- Node中的net模块提供的前端通信
Node中的net模块提供的前端通信 客户端 业务: 客户端现在要在终端输入内容,然后回车发送内容给服务器 解决: Node中提供了一个叫做 readline 的 模块用于读取命令行内容 [ 单行读取 ...
随机推荐
- java端口扫描(原创)
项目需要扫描占用的端口来判断服务是否启动,通过查资料发现大多数方法都是ServerSocket socket = new ServerSocket(port);代码如下: package com.fr ...
- 快速理解Java中的五种单例模式
解法一:只适合单线程环境(不好) package test; /** * @author xiaoping * */ public class Singleton { private static S ...
- java common-io jar API
import org.apache.commons.beanutils.BeanUtils;public class Person { private String name; public Stri ...
- valgind使用错误——检测不同位目标程序
当64位的valgrind工具测试32位的程序时,会报如下错误: ==22235== Memcheck, a memory error detector ==22235== Copyright (C) ...
- sublime test 3 使用及常用插件
1.家里不能安装问题 公司可以安装,但回到家里安装不上 package control,看了是网络方面原因,具体就没去了解... 所有建议: 安装后在sublime text目录下 新建 Date目录 ...
- knockout 学习实例6 attr
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- C++模板编程里的主版本模板类、全特化、偏特化(C++ Type Traits)
1. 主版本模板类 首先我们来看一段初学者都能看懂,应用了模板的程序: 1 #include <iostream> 2 using namespace std; 3 4 template ...
- Intellij Idea系列之导Jar包与编写单元测试(二)
Intellij Idea系列之导Jar包与编写单元测试(二) 一.初衷 对于很多的初学者来说,Intellij如何导入jar包感到很迷惑,甚至在网上搜过相关文章之后还是云里雾里,本博客通过图文并茂 ...
- Java 大数运算
import java.util.*; import java.math.*; public class Main{ public static void main(String args[]){ S ...
- Wampserver2.5配置虚拟主机出现403 Forbidden解决办法
一直在用APMServ5.2.6,mysql好办,可以用mariadb代替进行升级,但php升级到5.4.7就没办法再升级,安装加速器也困难.就想迁移到Wampserver上来,以前也尝试过Wamps ...