如何在Nodejs中使用模块fs文件系统

2022-04-15 0 1,161
目录
  • 概述
  • 文件描述符
  • 同步、异步与Promise
    • 同步写法
    • 异步写法
    • (推荐)Promise写法
  • 目录与目录项
    • 文件信息
      • ReadStream与WriteStream

        概述

        node 的fs文档密密麻麻的 api 非常多,毕竟全面支持对文件系统的操作。文档组织的很好,操作基本分为文件操作、目录操作、文件信息、流这个大方面,编程方式也支持同步、异步和 Promise。

        本文记录了几个文档中没详细描写的问题,可以更好地串联fs文档思路:

        • 文件描述符
        • 同步、异步与 Promise
        • 目录与目录项
        • 文件信息
        • stream

        文件描述符

        文件描述符是一个非负整数。它是一个索引值,操作系统可以根据它来找到对应的文件。

        在 fs 的很多底层 api 中,需要用到文件描述符。在文档中,描述符通常用fd来代表。例如:fs.read(fd, buffer, offset, length, position, callback)。与这个 api 相对应的是:fs.readFile(path[, options], callback)。

        因为操作系统对文件描述符的数量有限制,因此在结束文件操作后,别忘记 close:

        const fs = require("fs");
        
        fs.open("./db.json", "r", (err, fd) => {
            if (err) throw err;
            // 文件操作...
            // 完成操作后,关闭文件
            fs.close(fd, err => {
                if (err) throw err;
            });
        });

        同步、异步与 Promise

        所有文件系统的 api 都有同步和异步两种形式。

        同步写法

        不推荐使用同步 api,会阻塞线程。

        try {
            const buf = fs.readFileSync("./package.json");
            console.log(buf.toString("utf8"));
        } catch (error) {
            console.log(error.message);
        }

        异步写法

        异步写法写起来容易进入回调地狱。

        fs.readFile("./package.json", (err, data) => {
            if (err) throw err;
            console.log(data.toString("utf8"));
        });

        (推荐)Promise 写法

        在 node v12 之前,需要自己借助 promise 封装:

        function readFilePromise(path, encoding = "utf8") {
            const promise = new Promise((resolve, reject) => {
                fs.readFile(path, (err, data) => {
                    if (err) return reject(err);
                    return resolve(data.toString(encoding));
                });
            });
            return promise;
        }
        
        readFilePromise("./package.json").then(res => console.log(res));

        在 node v12 中,引入了 fs Promise api。它们返回 Promise 对象而不是使用回调。 API 可通过require(‘fs’).promises访问。如此一来,开发成本更低了。

        const fsPromises = require("fs").promises;
        
        fsPromises
            .readFile("./package.json", {
                encoding: "utf8",
                flag: "r"
            })
            .then(console.log)
            .catch(console.error);

        目录与目录项

        fs.Dir 类:封装了和文件目录相关的操作

        fs.Dirent 类:封装了目录项的相关操作。例如判断设备类型(字符、块、FIFO 等)。

        它们之间的关系,通过代码展示:

        const fsPromises = require("fs").promises;
        
        async function main() {
            const dir = await fsPromises.opendir(".");
            let dirent = null;
            while ((dirent = await dir.read()) !== null) {
                console.log(dirent.name);
            }
        }
        
        main();

        文件信息

        fs.Stats 类:封装了文件信息相关的操作。它在fs.stat()的回调函数中返回。

        fs.stat("./package.json", (err, stats) => {
            if (err) throw err;
            console.log(stats);
        });

        注意,关于检查文件是否存在:

        • 不建议在调用 fs.open()、 fs.readFile() 或 fs.writeFile() 之前使用 fs.stat() 检查文件是否存在。而是应该直接打开、读取或写入文件,如果文件不可用则处理引发的错误。
        • 要检查文件是否存在但随后并不对其进行操作,则建议使用 fs.access()

        ReadStream 与 WriteStream

        在 nodejs 中,stream 是个非常重要的库。很多库的 api 都是基于 stream 来封装的。例如下面要说的 fs 中的 ReadStream 和 WriteStream。

        fs 本身提供了 readFile 和 writeFile,它们好用的代价就是性能有问题,会将内容一次全部载入内存。但是对于几 GB 的大文件,显然会有问题。

        那么针对大文件的解决方案自然是:一点点读出来。这就需要用到 stream 了。以 readStream 为例,代码如下:

        const rs = fs.createReadStream("./package.json");
        let content = "";
        
        rs.on("open", () => {
            console.log("start to read");
        });
        
        rs.on("data", chunk => {
            content += chunk.toString("utf8");
        });
        
        rs.on("close", () => {
            console.log("finish read, content is:\n", content);
        });

        借助 stream 的 pipe,一行快速封装一个大文件的拷贝函数:

        function copyBigFile(src, target) {
            fs.createReadStream(src).pipe(fs.createWriteStream(target));
        }

        以上就是如何在Nodejs中使用模块fs文件系统的详细内容,更多关于Nodejs的资料请关注NICE源码其它相关文章!

        免责声明:
        1、本网站所有发布的源码、软件和资料均为收集各大资源网站整理而来;仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 不得使用于非法商业用途,不得违反国家法律。否则后果自负!

        2、本站信息来自网络,版权争议与本站无关。一切关于该资源商业行为与www.niceym.com无关。
        如果您喜欢该程序,请支持正版源码、软件,购买注册,得到更好的正版服务。
        如有侵犯你版权的,请邮件与我们联系处理(邮箱:skknet@qq.com),本站将立即改正。

        NICE源码网 JavaScript 如何在Nodejs中使用模块fs文件系统 https://www.niceym.com/34281.html