Nodejs 第二十章(fs 上)

概述

在 Node.js 中,fs 模块是文件系统模块(File System module)的缩写,它提供了与文件系统进行交互的各种功能。通过 fs 模块,你可以执行诸如读取文件、写入文件、更改文件权限、创建目录等操作,Node.js 核心API之一

fs多种策略

js 复制代码
import fs from 'node:fs'
import fs2 from 'node:fs/promises'
//读取文件
fs2.readFile('./index.txt').then(result => {
    console.log(result.toString())
})
fs.readFile('./index.txt', (err, data) => {
    if (err) {
        return err
    }
    console.log(data.toString())
})
let txt = fs.readFileSync('./index.txt')
console.log(txt.toString())
  1. fs支持同步和异步两种模式 增加了Sync fs 就会采用同步的方式运行代码,会阻塞下面的代码,不加Sync就是异步的模式不会阻塞。

  2. fs新增了promise版本,只需要在引入包后面增加/promise即可,fs便可支持promise回调。

  3. fs返回的是一个buffer二进制数据 每两个十六进制数字表示一个字节

js 复制代码
<Buffer 31 e3 80 81 e9 82 a3 e4 b8 80 e5 b9 b4 e5 86 b3 e8 b5 9b ef bc 8c e6 98 af 53 53 47 e5 af b9 e6 88 98 53 4b 54 ef bc 8c e6 9c 80 e7 bb 88 e6 af 94 e5 ... 635 more bytes>

常用API 介绍

读取文件 readFile 读一个参数 读取的路径, 第二个参数是个配置项

encoding 支持各种编码 utf-8之类的

flag 就很多了

  • 'a': 打开文件进行追加。 如果文件不存在,则创建该文件。

  • 'ax': 类似于 'a' 但如果路径存在则失败。

  • 'a+': 打开文件进行读取和追加。 如果文件不存在,则创建该文件。

  • 'ax+': 类似于 'a+' 但如果路径存在则失败。

  • 'as': 以同步模式打开文件进行追加。 如果文件不存在,则创建该文件。

  • 'as+': 以同步模式打开文件进行读取和追加。 如果文件不存在,则创建该文件。

  • 'r': 打开文件进行读取。 如果文件不存在,则会发生异常。

  • 'r+': 打开文件进行读写。 如果文件不存在,则会发生异常。

  • 'rs+': 以同步模式打开文件进行读写。 指示操作系统绕过本地文件系统缓存。

    这主要用于在 NFS 挂载上打开文件,因为它允许跳过可能过时的本地缓存。 它对 I/O 性能有非常实际的影响,因此除非需要,否则不建议使用此标志。

    这不会将 fs.open()fsPromises.open() 变成同步阻塞调用。 如果需要同步操作,应该使用类似 fs.openSync() 的东西。

  • 'w': 打开文件进行写入。 创建(如果它不存在)或截断(如果它存在)该文件。

  • 'wx': 类似于 'w' 但如果路径存在则失败。

  • 'w+': 打开文件进行读写。 创建(如果它不存在)或截断(如果它存在)该文件。

  • 'wx+': 类似于 'w+' 但如果路径存在则失败。

js 复制代码
import fs2 from 'node:fs/promises'

fs2.readFile('./index.txt',{
    encoding:"utf8",
    flag:"",
}).then(result => {
    console.log(result.toString())
})

使用可读流读取 使用场景适合读取大文件

js 复制代码
const readStream = fs.createReadStream('./index.txt',{
    encoding:"utf8"
})

readStream.on('data',(chunk)=>{
    console.log(chunk)
})

readStream.on('end',()=>{
    console.log('close')
})

创建文件夹 如果开启 recursive 可以递归创建多个文件夹

js 复制代码
fs.mkdir('path/test/ccc', { recursive: true },(err)=>{

})

删除文件夹 如果开启recursive 递归删除全部文件夹

js 复制代码
fs.rm('path', { recursive: true },(err)=>{

})

重命名文件 第一个参数原始名称 第二个参数新的名称

js 复制代码
fs.renameSync('./test.txt','./test2.txt')

监听文件的变化 返回监听的事件如change,和监听的内容filename

js 复制代码
fs.watch('./test2.txt',(event,filename)=>{
    
    console.log(event,filename)
})

源码解析

github.com/libuv/libuv

fs的源码是通过 C++ 层的 FSReqCallback 这个类 对libuvuv_fs_t 的一个封装,其实也就是将我们fs 的参数透传给 libuv

mkdir 举例

cc 复制代码
// 创建目录的异步操作函数,通过uv_fs_mkdir函数调用
// 参数:
// - loop: 事件循环对象,用于处理异步操作
// - req: 文件系统请求对象,用于保存操作的状态和结果
// - path: 要创建的目录的路径
// - mode: 目录的权限模式 777 421
// - cb: 操作完成后的回调函数
int uv_fs_mkdir(uv_loop_t* loop,
                uv_fs_t* req,
                const char* path,
                int mode,
                uv_fs_cb cb) {
  INIT(MKDIR);
  PATH;
  req->mode = mode;
  if (cb != NULL)
    if (uv__iou_fs_mkdir(loop, req))
      return 0;
  POST;
}

注意事项

js 复制代码
const fs = require('node:fs')

fs.readFile('./index.txt', {
    encoding: 'utf-8',
    flag: 'r'
}, (err, dataStr) => {
    if (err) throw err
    console.log('fs')
})

setImmediate(() => {
    console.log('setImmediate')
})

为什么先走setImmediate 呢,而不是fs

Node.js 读取文件的时候是使用libuv进行调度的

而setImmediate是由V8进行调度的

文件读取完成后 libuv 才会将 fs的结果 推入V8的队列

相关推荐
开心工作室_kaic17 分钟前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿36 分钟前
webWorker基本用法
前端·javascript·vue.js
cy玩具1 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
qq_390161772 小时前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test2 小时前
js下载excel示例demo
前端·javascript·excel
Yaml42 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事2 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶2 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
getaxiosluo2 小时前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx
理想不理想v2 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript