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+' 相似,但如果路径已存在则失败。
  • 相关阅读:
    HDU 2639 Bone Collector II (01背包,第k解)
    POJ 2184 Cow Exhibition 奶牛展(01背包,变形)
    hihoCoder #1165 : 益智游戏 (挑战赛11 B题)
    UVA 562 Dividing coins 分硬币(01背包,简单变形)
    POJ Charm Bracelet 挑饰品 (常规01背包)
    hiho一下 第四十四周 博弈游戏·Nim游戏(直接公式解)
    UVA 624 CD(01背包,要记录路径)
    118 Pascal's Triangle 帕斯卡三角形 杨辉三角形
    117 Populating Next Right Pointers in Each Node II 每个节点的右向指针 II
    116 Populating Next Right Pointers in Each Node 每个节点的右向指针
  • 原文地址:https://www.cnblogs.com/JHelius/p/11645872.html
Copyright © 2011-2022 走看看