fs 模块

fs 模块可以对文件进行操作

引入

import fs from 'fs'
const fs = require('fs')

文件夹

创建文件夹

在当前目录下创建一个 demo 文件夹,如果错误值为 EEXIST 则说明文件夹已存在

fs.mkdir('./demo', err => {
    if (err?.code === 'EEXIST') {
        console.log('目录已存在')
    }
})

删除文件夹

删除当前目录下的 demo 文件夹

fs.rmdir('./demo', err => {
    if (err?.code === 'ENOENT') {
        console.log('目录不存在')
    }
})

文件夹重命名

重命名当前目录下的 demo 文件夹为 demoo

fs.rename('./demo', './demoo', err => {
    if (err?.code === 'ENOENT') {
        console.log('文件不存在')
    }
})

获取文件夹内容

获取文件夹中的文件名,返回一个数组

fs.readdir('./demo', (err, data) => {
    if (!err) {
        console.log(data)
    }
})

文件

创建文件

在 demo 文件夹下创建一个名为 a 的 txt 文件,并写入内容 hello world

fs.writeFile('./demo/a.txt', 'hello world', err => {
    console.log(err)
})

追加内容

在文件中新增内容

fs.appendFile('./demo/a.txt', '\nhello world', err => {
    console.log(err)
})

删除文件

删除 demo 文件夹中的 a.txt

fs.unlink('./demo/a.txt', err => {
    console.log(err)
})

同步和异步

以上操作都是异步操作,如果需要同步的话可以尝试方法名加上 Sync

fs.writeFileSync()
fs.mkdirSync()
// ...

阻塞

同步会阻塞服务器进程,不建议使用

promises

现在异步都是回调函数的方式,可以使用 fs 模块提供的 promises 来进行 promise 异步操作

import { promises } from 'fs'

promises
    .readdir('./demo')
    .then(data => {
        console.log(data)
    })
    .catch(err => {
        console.log(err)
    })

删除有文件的文件夹

当文件夹中有文件的时候是无法使用 rmdir 删除文件夹的,现在来写一个函数实现

const deleteDir = (dir = './demo') => {
    promises.readdir(dir).then(async data => {
        await Promise.all(data.map(item => promises.unlink(`${dir}/${item}`)))
        await promises.rmdir(dir)
    })
}

再升级一下,用 stat 方法判断是否是文件夹,实现深层文件夹删除

const deleteDeepDir = async (dir = './demo') => {
    const data = await promises.readdir(dir)

    for (const file of data) {
        const path = `${dir}/${file}`

        if ((await promises.stat(path)).isDirectory()) {
            await deleteDir(path)
        } else {
            await promises.unlink(path)
        }
    }

    await promises.rmdir(dir)
}

如果对很大的文件直接进行读写的话可能会有性能上的问题,这个时候就可以使用文件流分段式读写(就像水流一样)

读取流

创建

const rs = fs.createReadStream('./demo/a.txt', 'utf-8')

读取

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

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

写入流

创建

const ws = fs.createWriteStream('./demo/a.txt', 'utf-8')

写入

for (let i = 0; i < 10; i++) {
    ws.write(`this is ${i + 1} \n`)
}

ws.end()

管道

如果想复制一个文件,那么可以通过管道,让数据从读取流流向写入流

fs.createReadStream('./demo/a.txt', 'utf-8').pipe(
    fs.createWriteStream('./demo/b.txt', 'utf-8')
)