Node.js核心API(fs篇)

发布于:2025-07-05 ⋅ 阅读:(20) ⋅ 点赞:(0)

前言:

        在Node.js生态系统中,文件系统操作是后端开发不可或缺的一部分。fs模块作为Node.js核心API的重要组成部分,提供了与文件系统交互的能力,涵盖了从基础的文件读写到复杂的目录操作等功能。

        现代JavaScript开发中,处理本地文件是常见需求,无论是配置文件读取、日志记录还是数据持久化存储。fs模块通过同步和异步两种方式提供这些功能,适应不同场景的性能要求。

        随着Node.js版本的迭代,fs模块不断加入新的特性,如Promise-based API的引入,使得文件操作能够更好地融入现代异步编程模式。理解并掌握fs模块,对于构建健壮的Node.js应用具有重要意义。

        本部分内容将深入解析fs模块的核心功能,包括常用方法的原理和使用场景,帮助开发者高效安全地处理文件系统操作,为构建复杂应用打下坚实基础。

1.读取文件

1.同步

        使用readFileSync方法,它的写法简洁,但会阻塞后面的代码执行,基本代码如下:

const fs = require('fs')

// 同步写法 会阻塞后面代码执行
const read = fs.readFileSync('./a.txt', 'utf8')
console.log(read)

        在终端中使用 node 文件名 将内容打印出来

        readFileSync('需要读取文件的文件名', '编码')

2.异步

        使用readFile方法,它接收三个参数,第一个是需要读取文件的文件名,第二个参数可以接受一个对象,可以在里面设置一些行为,就比如说设置读取到文字的编码,第三个参数接受一个回调函数,基本的写法如下:

const fs = require('fs')

// 异步
fs.readFile('./a.txt', {
    encoding: 'utf8', // 编码
    flag: 'r' // 读取
}, (err, data) => {
    if (err) throw err // 将错误抛出
    console.log(data)
})

3.promise

        这种写法就可以通过.then或.catch来处理成功或失败的结果,我个人还是推荐使用这种写法。代码如下:

const fs = require('fs/promises')

// promise
fs.readFile('./a.txt').then(result => {
    console.log(result.toString('utf8'));
}).catch(err => {
    throw err
}).finally(()=>{
    console.log('不管成功与否我都执行');
})

        看到这可能有些人有点蒙,为什么编码有这么多种写法,其实这三种都是可以的,看个人习惯,以及需求。

4.可读流

        在处理大文件时会使用到可读流,它会将文件里的内容一点一点传过来,假设有一个很大内存的文件,不可能使用readFile一直等着,代码如下:

const fs = require('fs')

// 可读流 处理大文件
const readStream = fs.createReadStream('./a.txt')

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

readStream.on('end', () => {
    console.log('读取完成了')
})

2.创建文件夹

        使用到了mkdirSync,一般都是同步的,因为创建一个文件夹的速度是非常快的。代码如下:

const fs = require('fs')

// 创建文件夹
fs.mkdirSync('./a')

        如果需要创建一个嵌套的文件夹,会发现比如将路径改为./a/b/c,这样是不行的,那如何创建呢,可以使用递归,当然不用我们直接写,只需要添加第二个参数即可,代码如下:

const fs = require('fs')

// 创建嵌套文件夹
fs.mkdirSync('./a/b/c', {
    recursive: true
})

3.删除

        这个比较简单,使用rm方法,命名跟Linux差不多。代码如下:

const fs = require('fs')

// 删除
fs.rmSync('./a', {
    recursive: true
})

        如果是嵌套的文件夹,只需要递归删除即可。

4.重命名

const fs = require('fs')

// 重命名
fs.renameSync('./a.txt', './b.txt')

        第一个参收是需要重命名文件名称,第二个参数是要修改的名称。

5.监听文件的变化

        使用watch方法,许多热更新的底层原来就用到了这个。代码如下:

const fs = require('fs')

// 监听文件的变化
fs.watch('./a.txt', (event, filename) => {
    console.log(event, filename);
})

        当我修改a.txt中的内容时,这个事件就会触发

6.写入文件

        使用writeFile或writeFileSync方法,代码如下:

const fs = require('fs')

// 写入文件
fs.writeFileSync('./a.txt', '666')

        当运行脚本会发现,它会将原来文本里面的内容替换成我们写入的内容,而不是追加,接下来就来说追加的操作。

7.追加写入文件

1.第一种方法(writeFileSync)

        写入的方法也有追加的功能,添加第三个参数,代码如下:

const fs = require('fs')

// 追加文件
fs.writeFileSync('./a.txt', '\n777', {
    flag: 'a'
})

        a的意思是append追加的意思

2.第二种方法(appendFileSync)

const fs = require('fs')

// 追加文件
fs.appendFileSync('./a.txt', '\n888')

8.可写流

        从名字可以看出和可读流类似,可以回顾一下可读流的意思就可以大致猜到可写流是什么意思。

        可写流的意思就是将大量的数据分批插入。

const fs = require('fs')

// 可写流

const writeStream = fs.createWriteStream('./a.txt')

const data = [
    "青山衔落日,",
    "碧水映霞飞。",
    "风过荷香漫,",
    "蝉鸣暮色微。",
    "孤舟横野渡,",
    "倦鸟宿林扉。",
    "欲寄乡思远,",
    "星河入梦归。"
]

data.forEach(item => {
    writeStream.write(item + '\n')
})

// 记得关闭 不然通道一直打开
writeStream.end()

// 也可以添加事件 就比如通知写入完成
writeStream.on('finish',() => {
    console.log('写入完成');
})

结语:

        Node.js的fs模块为开发者提供了强大而灵活的文件系统操作能力,覆盖从基础读写到高级流处理的各类场景。通过同步、异步和Promise三种模式,开发者可根据项目需求选择最佳实践方式,平衡代码可读性与性能要求。

        文件流处理技术(可读流/可写流)尤其适合大文件操作场景,有效避免内存压力。目录创建与删除的递归选项、文件监听机制等特性,为构建自动化工具和实时系统提供了底层支持。

        现代JavaScript开发中,建议优先考虑Promise-based API或异步模式,结合错误处理机制构建健壮的应用。掌握这些核心方法后,开发者可以高效实现配置文件管理、日志系统、数据持久化等关键功能,为复杂Node.js应用奠定坚实基础。