zoukankan      html  css  js  c++  java
  • Node.js入门教程 第四篇 (流及文件操作)

    Stream是Node.js中的抽象接口,有不少Node.js对象实现自Stream。

    所有的Stream对象都是EventEmitter 的实例。

    例如:fs模块(用于读写操作文件的模块)

    fs的FSWatcher接口继承自events.EventEmitter,以下是fs模块的部分源码:

     1 interface FSWatcher extends events.EventEmitter {
     2     close(): void;
     3     /**
     4      * events.EventEmitter
     5      *   1. change
     6      *   2. error
     7      */
     8     addListener(event: string, listener: (...args: any[]) => void): this;
     9     addListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this;
    10     addListener(event: "error", listener: (error: Error) => void): this;
    11     on(event: string, listener: (...args: any[]) => void): this;
    12     on(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this;
    13     on(event: "error", listener: (error: Error) => void): this;
    14     once(event: string, listener: (...args: any[]) => void): this;
    15     once(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this;
    16     once(event: "error", listener: (error: Error) => void): this;
    17 
    18     prependListener(event: string, listener: (...args: any[]) => void): this;
    19     prependListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this;
    20     prependListener(event: "error", listener: (error: Error) => void): this;
    21     prependOnceListener(event: string, listener: (...args: any[]) => void): this;
    22     prependOnceListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this;
    23     prependOnceListener(event: "error", listener: (error: Error) => void): this;
    24 }

    在源码中我们可以看出,fs模块提供了不少的事件,如“error”、“change”等。 通过事件监听,我们可以方便的监控文件操作时的状态,例如可以监听error事件来判断文件读写是否出错。

    对流的操作一般由以下几种:

    1、读取流

    1 var fs = require("fs");
    2 var readerStream = fs.createReadStream('test.txt');//读取test文件

    2、写入流

    1 var fs = require("fs");
    2 var writerStream = fs.createWriteStream('test.txt');
    3 writerStream.write('test_data','UTF8');//写入test文件

    3、管道流,即输出流转入输入流(可用于文件下载)

    1 var fs = require("fs");
    2 var readerStream = fs.createReadStream('input.txt');
    3 var writerStream = fs.createWriteStream('output.txt');
    4 readerStream.pipe(writerStream);

    4、链式流, 链式是通过连接输出流到另外一个流并创建多个流操作链的机制

    1 var fs = require("fs");
    2 var zlib = require('zlib');//压缩及解压缩模块
    3 //压缩input.txt到input.txt.gz
    4 fs.createReadStream('input.txt')
    5   .pipe(zlib.createGzip())
    6   .pipe(fs.createWriteStream('input.txt.gz'));

    利用流的特性我们写一个文件下载的范例:

     1 const fs = require("fs");
     2 module.exports = {
     3     downloadApp(req, res, next) {
     4         var name = "XXX.apk";
     5         var path = 'download_file/' + name;
     6         fs.exists(path, function (exists) {
     7             if (exists) {
     8                 var size = fs.statSync(path).size;
     9                 var f = fs.createReadStream(path);
    10                 f.on('error', function (err) {//监听error事件判断文件读写是否出错
    11                     console.log(err.stack);
    12                     //此处可以记log
    13                    });
    14                 res.writeHead(200, {
    15                     'Content-Type': 'application/force-download',
    16                     'Content-Disposition': 'attachment; filename=' + name,
    17                     'Content-Length': size
    18                 });
    19                 f.pipe(res);//将读取的文件流写入输出流
    20             }
    21         });
    22     },
    23 }

    Node.js的文件操作

    Node.js中有对文件操作功能非常丰富的模块,就是在上文中我们提到的fs模块。fs模块的所有文件操作函数都提供同步和异步,不过通常使用异步较多(非阻塞特性)。

     1 var fs = require("fs");
     2 // 异步读取
     3 fs.readFile('test.txt', function (err, data) {
     4    if (err) {
     5        return console.error(err);
     6    }
     7    console.log("异步读取: " + data.toString());
     8 });
     9 // 同步读取
    10 var data = fs.readFileSync('test.txt');
    11 console.log("同步读取: " + data.toString());

    除此之外,fs提供了众多操作,以下是其中一部分:

    fs.open(path[, flags[, mode]], callback)

    fs.write(fd, buffer[, offset[, length[, position]]], callback)

    fs.writeFile(file, data[, options], callback)

    当 flag 选项采用字符串时,可用以下标志:

    • 'a' - 打开文件用于追加。如果文件不存在,则创建该文件。
    • 'ax' - 与 'a' 相似,但如果路径已存在则失败。
    • 'a+' - 打开文件用于读取和追加。如果文件不存在,则创建该文件。
    • 'ax+' - 与 'a+' 相似,但如果路径已存在则失败。
    • 'as' - 以同步模式打开文件用于追加。如果文件不存在,则创建该文件。
    • 'as+' - 以同步模式打开文件用于读取和追加。如果文件不存在,则创建该文件。
    • 'r' - 打开文件用于读取。如果文件不存在,则出现异常。
    • 'r+' - 打开文件用于读取和写入。如果文件不存在,则出现异常。
    • 'w' - 打开文件用于写入。如果文件不存在则创建文件,如果文件已存在则截断文件。
    • 'wx' - 与 'w' 相似,但如果路径已存在则失败。
    • 'w+' - 打开文件用于读取和写入。如果文件不存在则创建文件,如果文件已存在则截断文件。
    • 'wx+' - 与 'w+' 相似,但如果路径已存在则失败。
  • 相关阅读:
    《学习之道》第六章总结
    《学习之道》第六章一心多用
    《学习之道》第六章无视干扰
    《学习之道》第六章番茄工作法
    《学习之道》第六章关注过程,亦培养习惯
    《学习之道》第六章学习方法23与小恶魔较劲
    《学习之道》第六章习惯的部分-信念
    《学习之道》第六章习惯的部分-奖励机制
    《学习之道》第六章习惯的部分-反应程序
    使用Python验证常见的50个正则表达式
  • 原文地址:https://www.cnblogs.com/JHelius/p/11645872.html
Copyright © 2011-2022 走看看