• Node.js精进(6)——文件


    🚀 优质资源分享 🚀

    学习路线指引(点击解锁)知识定位人群定位
    🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
    💛Python量化交易实战💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

    文件系统是一种用于向用户提供底层数据访问的机制,同时也是一套实现了数据的存储、分级组织、访问和获取等操作的抽象数据类型。

    Node.js 中的fs模块就是对文件系统的封装,整合了一套标准 POSIX 文件 I/O 操作的集合,包括文件的读写、删除、遍历、重命名等操作。

    fs 模块中的所有方法都提供了三种形式:回调、同步和 Promise ,其中 Promise 是在 Node.js 的版本 10 中引入的。

    本系列所有的示例源码都已上传至Github,点击此处获取。

    一、三种形式

    在回调形式的方法中,最后一个参数是其回调函数,会异步地调用,其中回调函数的第一个参数始终为异常预留,不过有个例外是 exists() 方法。

    回调形式不容易书写,很容易就会形成回调地狱。

    虽然同步形式的方法比较容易书写,但是在执行时会阻止 Node.js 事件循环和阻塞 JavaScript 执行,直到操作完成。

    Promise 形式的方法会使用底层的 Node.js 线程池,在事件循环线程之外异步地执行文件系统操作。对同一文件执行多个并发修改时必须小心,有可能会损坏数据。

    以读取文件为例,三种形式的写法如下所示,若不指定编码,那么输出的将是 Buffer 实例。

    const fs = require('fs');
    // 回调
    fs.readFile('./data.txt', 'utf8', (err, data) => {
     if (err) throw err;
     console.log(data); // strick
    });
    
    // 同步
    const data = fs.readFileSync('./data.txt', 'utf8');
    console.log(data); // strick
    
    // Promise
    const { promises } = fs;
    async function readFilePromise() {
     const data = await promises.readFile('./data.txt', 'utf8');
     console.log(data); // strick
    }
    readFilePromise();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    二、基础使用

    1)判断文件是否存在

    exists() 方法可用于判断文件是否存在,但在上一小节中曾提到,它已被弃用。

    这是因为此回调的参数与其他回调不一致。通常,Node.js 回调的第一个参数是 err 参数,然后跟可选的其他参数,但 fs.exists() 回调只有一个布尔参数,如下所示。

    fs.exists('./data.txt', isExist => {
     console.log(isExist);
    });
    
    • 1
    • 2
    • 3

    再则是因为 exists() 方法的功能用 access() 方法也能实现,其内部源码如下所示,其实也是调用了 access() 方法。

    function exists(path, callback) {
     maybeCallback(callback);
     // 构造回调函数
      function suppressedCallback(err) {
     callback(err ? false : true);
     }
     try {
     fs.access(path, F\_OK, suppressedCallback);
     } catch {
     return callback(false);
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    其中 F_OK 是 fs 模块中的一个常量,表示文件是否存在,使用方法如下所示,R_OK 表示是否可读,W_OK 表示是否可写。

    const { constants } = require('fs');
    const { F\_OK, R\_OK, W\_OK } = constants;
    
    • 1
    • 2

    注意,在调用 fs.open()、fs.readFile() 或 fs.writeFile() 之前,不能使用 fs.access() 检查文件是否存在。

    因为这样做会引入竞争条件,其他进程可能会在两次调用之间修改文件状态,造成非预期的结果。

    遇到这种场景,推荐的做法是直接打开、读取或写入文件,当文件不可用时再做处理。

    另一种判断文件是否存在的方法是调用 stat(),读取文件属性。

    它有两个方法 isDirectory() 和 isFile() 可分别判断是否是目录和是否是文件,如下所示。

    fs.stat('./data.txt', (err, stats) => {
     console.log(stats.isDirectory());
     console.log(stats.isFile());
    });
    
    • 1
    • 2
    • 3
    • 4

    同样要注意的是,它也不能在调用 fs.open()、fs.readFile() 或 fs.writeFile() 之前,检查文件是否存在。

    2)方法

    下面罗列的是 fs 模块的一些方法。

    • fs.open():打开文件,可设置文件模式。
    • fs.close():关闭文件描述符。
    • fs.createReadStream():创建可读的文件流。
    • fs.createWriteStream():创建可写的文件流。
    • fs.readFile():读取文件的内容,相关方法:fs.read()。
    • fs.writeFile():写入文件,相关方法:fs.write()。
    • fs.link():新建指向文件的硬链接。
    • fs.unlink():删除文件或符号链接。
    • fs.mkdir():新建文件夹。
    • fs.rmdir():删除文件夹。
    • fs.readdir():读取目录的内容。
    • fs.stat():读取文件属性,相关方法:fs.fstat()、fs.lstat()。
    • fs.access():检查文件是否存在,以及 Node.js 是否有权限访问。
    • fs.rename():重命名文件或文件夹。
    • fs.appendFile():追加数据到文件,如果文件不存在,则创建文件。
    • fs.copyFile():拷贝文件,可覆盖文件内容。
    • fs.chmod():更改文件(通过传入的文件名指定)的权限,相关方法:fs.lchmod()、fs.fchmod()。
    • fs.chown():更改文件(通过传入的文件名指定)的所有者和群组,相关方法:fs.fchown()、fs.lchown()。
    • fs.watchFile():开始监控文件的更改,相关方法:fs.watch()。
    • fs.unwatchFile():停止监控文件的更改。

    3)路径

    路径处理并不是在 fs 模块,而是在path模块,它的方法包括。

    • path.basename():读取路径的最后一部分。
    • path.dirname():读取路径的目录部分。
    • path.extname():读取路径的文件扩展名。
    • path.isAbsolute():判断是否是绝对路径。
    • path.join():将多个部分合并成一个完整的路径。
    • path.normalize():当包含类似 .、… 或 // 等相对的说明符时,就尝试计算实际的路径。
    • path.parse():解析成路径对象。
    • path.relative():基于当前目录,返回从第一个路径到第二个路径的相对路径。
    • path.resolve():将相对路径计算成绝对路径。
    path.basename('../06/data.txt')    // data.txt
    path.dirname('../06/data.txt');    // ../06
    path.extname('../06/data.txt');    // .txt
    path.isAbsolute('../06/data.txt');     // false
    path.join('../', '06', 'data.txt');    // ../06/data.txt
    path.normalize('/../06/data.txt');     // /06/data.txt
    // { root: '', dir: '../06', base: 'data.txt', ext: '.txt', name: 'data' }
    path.parse('../06/data.txt');
    path.relative('../', '../06/data.txt');    // 06/data.txt
    path.resolve('../06/data.txt');        // /Users/code/web/node/06/data.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    参考资料:

    判断文件存在

    深入Node.js源码之文件系统

    Node.js官网文档 API文件系统

    饿了么File

  • 相关阅读:
    docker swam 集群实现负载均衡
    02-Linux
    Selenium 选择器定位元素方式详解
    【Qt学习】第一个Qt Quick程序
    Linux下RTC驱动开发(硬件采用DS1302)
    他没有输出一直卡在后面不懂,看报错应该是卡在# 循环生成诗句了
    融合多策略的萤火虫算法求解多目标优化问题(Matlab代码实现)
    1.求指定宽度的文本的高度,2.ubuntu下ping ipv6,3.git提示:终止提交因为提交说明为空
    2022年最新山西水利水电施工安全员模拟试题题库及答案
    FreeRTOS个人笔记-FreeRTOSConfig.h
  • 原文地址:https://blog.csdn.net/u012804784/article/details/125519308