Node.js入门教程 第四篇 (流及文件操作)
流
Stream是Node.js中的抽象接口,有不少Node.js对象实现自Stream。
所有的Stream对象都是EventEmitter 的实例。
例如:fs模块(用于读写操作文件的模块)
fs的FSWatcher接口继承自events.EventEmitter,以下是fs模块的部分源码:
interface FSWatcher extends events.EventEmitter {
close(): void;
/**
* events.EventEmitter
* 1. change
* 2. error
*/
addListener(event: string, listener: (...args: any[]) => void): this;
addListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this;
addListener(event: "error", listener: (error: Error) => void): this;
on(event: string, listener: (...args: any[]) => void): this;
on(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this;
on(event: "error", listener: (error: Error) => void): this;
once(event: string, listener: (...args: any[]) => void): this;
once(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this;
once(event: "error", listener: (error: Error) => void): this;
prependListener(event: string, listener: (...args: any[]) => void): this;
prependListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this;
prependListener(event: "error", listener: (error: Error) => void): this;
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
prependOnceListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this;
prependOnceListener(event: "error", listener: (error: Error) => void): this;
}
在源码中我们可以看出,fs模块提供了不少的事件,如“error”、“change”等。 通过事件监听,我们可以方便的监控文件操作时的状态,例如可以监听error事件来判断文件读写是否出错。
对流的操作一般由以下几种:
1、读取流
var fs = require("fs");
var readerStream = fs.createReadStream('test.txt');//读取test文件
2、写入流
var fs = require("fs");
var writerStream = fs.createWriteStream('test.txt');
writerStream.write('test_data','UTF8');//写入test文件
3、管道流,即输出流转入输入流(可用于文件下载)
var fs = require("fs");
var readerStream = fs.createReadStream('input.txt');
var writerStream = fs.createWriteStream('output.txt');
readerStream.pipe(writerStream);
4、链式流, 链式是通过连接输出流到另外一个流并创建多个流操作链的机制
var fs = require("fs");
var zlib = require('zlib');//压缩及解压缩模块
//压缩input.txt到input.txt.gz
fs.createReadStream('input.txt')
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream('input.txt.gz'));
利用流的特性我们写一个文件下载的范例:
const fs = require("fs");
module.exports = {
downloadApp(req, res, next) {
var name = "XXX.apk";
var path = 'download_file/' + name;
fs.exists(path, function (exists) {
if (exists) {
var size = fs.statSync(path).size;
var f = fs.createReadStream(path);
f.on('error', function (err) {//监听error事件判断文件读写是否出错
console.log(err.stack);
//此处可以记log
});
res.writeHead(200, {
'Content-Type': 'application/force-download',
'Content-Disposition': 'attachment; filename=' + name,
'Content-Length': size
});
f.pipe(res);//将读取的文件流写入输出流
}
});
},
}
Node.js的文件操作
Node.js中有对文件操作功能非常丰富的模块,就是在上文中我们提到的fs模块。fs模块的所有文件操作函数都提供同步和异步,不过通常使用异步较多(非阻塞特性)。
var fs = require("fs");
// 异步读取
fs.readFile('test.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("异步读取: " + data.toString());
});
// 同步读取
var data = fs.readFileSync('test.txt');
console.log("同步读取: " + data.toString());
除此之外,fs提供了众多操作,以下是其中一部分:
fs.open(path[, flags[, mode]], callback)
- path <string> | <Buffer> | <URL>
- flags <string> | <number> 参阅支持的文件系统标志。默认值: 'r'。
- mode <integer> 默认值: 0o666(可读写)。
- callback <Function>
- err <Error>
- fd <integer>
fs.write(fd, buffer[, offset[, length[, position]]], callback)
- fd <integer>
- buffer <Buffer> | <TypedArray> | <DataView>
- offset <integer>
- length <integer>
- position <integer>
- callback <Function>
- err <Error>
- bytesWritten <integer>
- buffer <Buffer> | <TypedArray> | <DataView>
fs.writeFile(file, data[, options], callback)
- file <string> | <Buffer> | <URL> | <integer> 文件名或文件描述符。
- data <string> | <Buffer> | <TypedArray> | <DataView>
- options <Object> | <string>
- encoding <string> | <null> 默认值: 'utf8'。
- mode <integer> 默认值: 0o666。
- flag <string> 参阅支持的文件系统标志。默认值: 'w'。
- callback <Function>
- err <Error>
当 flag 选项采用字符串时,可用以下标志:
- 'a' - 打开文件用于追加。如果文件不存在,则创建该文件。
- 'ax' - 与 'a' 相似,但如果路径已存在则失败。
- 'a+' - 打开文件用于读取和追加。如果文件不存在,则创建该文件。
- 'ax+' - 与 'a+' 相似,但如果路径已存在则失败。
- 'as' - 以同步模式打开文件用于追加。如果文件不存在,则创建该文件。
- 'as+' - 以同步模式打开文件用于读取和追加。如果文件不存在,则创建该文件。
- 'r' - 打开文件用于读取。如果文件不存在,则出现异常。
- 'r+' - 打开文件用于读取和写入。如果文件不存在,则出现异常。
- 'w' - 打开文件用于写入。如果文件不存在则创建文件,如果文件已存在则截断文件。
- 'wx' - 与 'w' 相似,但如果路径已存在则失败。
- 'w+' - 打开文件用于读取和写入。如果文件不存在则创建文件,如果文件已存在则截断文件。
- 'wx+' - 与 'w+' 相似,但如果路径已存在则失败。
Node.js入门教程 第四篇 (流及文件操作)的更多相关文章
- Node.js入门教程 第五篇 (Express框架)
Express框架 Express是适用于Node.js web的框架,提供了大量实用功能,例如路由功能及http功能. Express 框架核心特性: 可以设置中间件来响应 HTTP 请求. 定义了 ...
- Node.js入门教程 第三篇 (模块及路由)
Node.js的模块 Node.js的模块与传统面向对象的类(class)不完全相同.Node.js认为文件即模块,即一个文件是一个模块.单一文件一般只专注做一件事情,保证了代码的简洁性. 创建模块: ...
- Node.js入门教程 第六篇 (连接使用MySql)
连接使用MySql 安装MySql模块: npm install mysql 创建连接: const mysql = require('mysql') // 连接 mysql 服务器 const co ...
- 【特别推荐】Node.js 入门教程和学习资源汇总
这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
- Node.js 入门教程和学习资源汇总
这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
- 极简 Node.js 入门 - 4.3 可读流
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- 极简 Node.js 入门 - 4.4 可写流
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- node.js 入门教程(beginnder guide
非常好的教程: node入门: JavaScript与Node.js JavaScript与你 简短申明 服务器端JavaScript “Hello World” 一个完整的基于Node.js的web ...
- Node.js入门教程:Node.js如何安装配置并部署第一个网站
前言:作为一个资深的前端开发人员,不懂的Node.js 那你绝对是不能跟别人说你是资深的前端程序猿滴! 今天洋哥就来和大家一起学习被大牛称之为前端必学的技能之一Node! 那么Node到底是什么呢? ...
随机推荐
- 实现一个基于码云Storage
实现一个简单的基于码云(Gitee) 的 Storage Intro 上次在 asp.net core 从单机到集群 一文中提到存储还不支持分布式,并立了一个 flag 基于 github 或者 开源 ...
- MYSQL之B+TREE索引原理
1.什么是索引? 索引:加速查询的数据结构. 2.索引常见数据结构 顺序查找: 最基本的查询算法-复杂度O(n),大数据量此算法效率糟糕. 二叉树查找:(binary tree search): O( ...
- Runtime.getRuntime().exec()实现Java调用python程序
使用Runtime.getRuntime().exec()来实现Java调用python,调用代码如下所示: import java.io.BufferedReader; import java.io ...
- 获取不到jdbc.driver的值解决办法
我存在的问题是: 1.先检查自己是否出错 ①首先想到mysql版本和驱动版本之间的冲突问题,我的mysql是5.5.56,驱动用的5.1.32,上网查了一下可以用,但还是尝试换了一个版本的驱动,还是出 ...
- ELKBR部署检测项目日志
ELK filebeat:具有日志收集功能,相比logstash,+filebeat更轻量,占用资源更少,适合客户端使用. redis消息队列选型:Redis 服务器通常都是用作 NoSQL 数据库, ...
- All Of ACM
数据结构和算法专栏,我会什么写什么 = = 不定时更新 一.数据结构 树状数组详解 线段树详解 二.算法 KMP算法 三.板子 我的代码模板 大整数模板 四.题解报告 几道STL题目(FJUT - ...
- Elastic Stack 笔记(四)Elasticsearch5.6 索引及文档管理
博客地址:http://www.moonxy.com 一.前言 在 Elasticsearch 中,对文档进行索引等操作时,既可以通过 RESTful 接口进行操作,也可以通过 Java 也可以通过 ...
- 夯实Java基础系列9:深入理解Class类和Object类
目录 Java中Class类及用法 Class类原理 如何获得一个Class类对象 使用Class类的对象来生成目标类的实例 Object类 类构造器public Object(); register ...
- Scala Basis
基础 Scala 中数据类型也是 class 7 种数值类型: Byte, Char, Short, Int, Long, Float, and Double Boolean 类型 原始类型与 cla ...
- java -PDF添加文本水印与图片水印
java pdf添加水印文本及图片文本 PDF文件添加文本水印: private static int interval = 30; public static void waterMark(Stri ...