• Node.js中9种必须要掌握的fs模块文件操作方法、文件夹递归删除知识


    在这里插入图片描述
    本文主要介绍了Node.js常用的文件操作方法,以及常见的处理场景,文件追加,文件夹递归删除等。

    Node.js中9种必须要掌握的文件操作方法

    一、前言

    1. fs.mkdir()
    2. fs.writeFile()
    3. fs.appendFile()
    4. fs.stat()
    5. fs.readFile()
    6. fs.readdir()
    7. fs.rename()
    8. fs.unlink()
    9. fs.rmdir()

    二、fs.mkdir()创建文件夹

    异步的创建一个文件夹。

    语法:

    fs.mkdir(path[,options],callback)
    /**
     * path <string> | <Buffer> | <URL>
     * options <Object> | <integer>
     * recursive <boolean> 默认值: false
     * mode <string> | <integer> Windows 上不支持。 默认值: 0o777。
     * callback <Function>
     * err <Error>
     * path <string> | <undefined> 仅当创建目录时将 recursive 设置为 true。
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.1 最简单的案例

    最简单的案例,在当前目录下创建一个temp文件夹:

    const fs = require('fs')
    
    fs.mkdir('./temp',(err)=>{
        if(err){
            console.log(err.message)
            return 
        }
        console.log('创建文件夹成功')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    代码执行结果:

    image-20220704150029913

    2.2 递归创建文件夹

    使用参数{recursive:true}创建多层次的文件夹。

    fs.mkdir('./parent/son/grandson',{recursive:true},(err,path)=>{
        if(err){
            console.log(err.message)
            return 
        }
        console.log('递归创建文件夹成功',path)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行结果:

    image-20220704150941247

    注意: 在使用{recursive:true}参数时,回调对应的会增加一个path参数,其他情况下没有。

    三、fs.wirteFile()创建、写文件

    file 是文件名时,将数据异步地写入文件,如果文件已存在则替换该文件。 data 可以是字符串或缓冲区。

    file 是文件描述符时,其行为类似于直接调用 fs.write()本文不涉及这种情况)。

    语法:

    fs.writeFile(file, data[, options], callback)
    /**
     * file <string> | <Buffer> | <URL> | <integer> 文件名或文件描述符
     * data <string> | <Buffer> | <TypedArray> | <DataView> | <Object>
     * options <Object> | <string>
     * encoding <string> | <null> 默认值: 'utf8'
     * mode <integer> 默认值: 0o666
     * flag <string> 请参阅对文件系统 flags 的支持。 默认值: 'w'。
     * signal <AbortSignal> 允许中止正在进行的写入文件
     * callback <Function>
     * err <Error> | <AggregateError>
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.1 创建并写入一个文件

    创建一个名为index.html的文件,并写入一行字符串。

    fs.writeFile('./index.html',"<h1>你好,中国</h1>",(err)=>{
        if(err){
            console.log(err.message)
            return 
        }
        console.log("创建写入文件成功")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行结果如下:

    image-20220704152812122

    3.2 重写文件并指定编码

    重写index.html,并为文件指定编码:

    fs.writeFile('./index.html','<h2>面朝大海,春暖花开</h2>','utf-8',(err)=>{
        if(err){
            console.log(err.message)
            return 
        }
        console.log('写入指定格式文件成功')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行效果如下:

    image-20220704154454936

    原文件内容被覆盖。

    3.3 写入GBK格式的文件

    Node.js仅支持utf8 ucs2 ascii binary base64 hex这几种格式,对于GBKGB2312等特殊格式需要使用额外的库(这里使用iconv-lite)。

    案例:

    const iconv = require('iconv-lite')
    fs.writeFile('./style.css',iconv.encode('面朝大海,春暖花开','gbk'),(err)=>{
        if(err){
            console.log(err.message)
            return 
        }
        console.log("以GBK格式写入成功")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    代码执行结果:

    image-20220704171140551

    注意底部的编码格式,如果使用utf-8打开文件会乱码的呦!

    四、fs.appendFile()文件后追加内容

    异步地将数据追加到文件,如果该文件尚不存在,则创建该文件。

    语法:

    fs.appendFile(path, data[, options], callback)
    /**
     * path <string> | <Buffer> | <URL> | <number> 文件名或文件描述符
     * data <string> | <Buffer>
     * options <Object> | <string>
     * encoding <string> | <null> 默认值: 'utf8'
     * mode <integer> 默认值: 0o666
     * flag <string> 请参阅对文件系统 flags 的支持。 默认值: 'a'。
     * callback <Function>
     * err <Error>
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4.1 使用追加的方式创建并写入内容

    fs.appendFile('./test.txt', '测试写入', (err) => {
        if (err) {
            console.log(err.message)
            return
        }
        console.log("使用追加的方式创建并写入文件")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行结果:

    image-20220704194103819

    4.2 追加内容

    fs.appendFile('./test.txt', "\n追加测试", (err) => {
        if (err) {
            console.log(err.message)
            return
        }
        console.log('在已经存在的文件中追加内容')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行结果:

    image-20220704194010770

    五、fs.stat()判断路径是目录还是文件

    判断路径是文件还是目录。

    语法:

     fs.stat(path[, options], callback)
    /**
     * path <string> | <Buffer> | <URL>
     * options <Object>
     * bigint <boolean> 返回的 <fs.Stats> 对象中的数值是否应为 bigint。 默认值: false。
     * callback <Function>
     * err <Error>
     * stats <fs.Stats>
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5.1 判断文件案例

    判断index.html是文件还是目录。

    fs.stat('./index.html',(err,stats)=>{
        if(err){
            console.log(err.message)
            return 
        }
        console.log(`./index.html是文件:${stats.isFile()}`)
        console.log(`./index.html是目录:${stats.isDirectory()}`)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    代码执行效果:

    image-20220704155406486

    六、fs.readFile()读取文件内容

    异步地读取文件的全部内容。

    语法:

    fs.readFile(path[, options], callback)
    /**
     * path <string> | <Buffer> | <URL> | <integer> 文件名或文件描述符
     * options <Object> | <string>
     * encoding <string> | <null> 默认值: null
     * flag <string> 请参阅对文件系统 flags 的支持。 默认值: 'r'。
     * signal <AbortSignal> 允许中止正在进行的读取文件
     * callback <Function>
     * err <Error> | <AggregateError>
     * data <string> | <Buffer>
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    6.1 以默认格式读取文件

    以默认的格式(utf-8)读取文件内容:

    fs.readFile('./index.html',(err,data)=>{
        if(err){
            console.log(err.message)
            return 
        }
        console.log(`读取文件成功,文件内容是:\n${data}`)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行结果:

    image-20220704162501845

    如果要读取的文件不是utf-8格式,就会出现乱码,这时就需要指定读取格式。

    6.2 以指定格式(这里是GBK)读取文件

    遗憾的是,node.js不支持除了utf8 ucs2 ascii binary base64 hex之外的编码,我们需要使用额外的包(iconv-lite)读取GBK文件:

    const iconv = require('iconv-lite')
    fs.readFile('./index.html',(err,data)=>{
        if(err){
            console.log(err.message)
            return 
        }
        console.log(`读取文件成功,文件内容是:\n${data}`)
        console.log("读取文件成功,文件内容是:\n",iconv.decode(data,'gbk'))
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    代码执行结果如下:

    image-20220704170140585

    七、fs.readdir()读取文件夹中的内容

    读取目录的内容。 回调有两个参数 (err, files),其中 files 是目录中文件名的数组,不包括 '.''..'

    语法:

    fs.readdir(path[, options], callback)
    /**
     * path <string> | <Buffer> | <URL>
     * options <string> | <Object>
     * encoding <string> 默认值: 'utf8'
     * withFileTypes <boolean> 默认值: false
     * callback <Function>
     * err <Error>
     * files <string[]> | <Buffer[]> | <fs.Dirent[]>
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    7.1 读取文件夹案例

    读取当前文件夹下所有的文件。

    fs.readdir('./',(err,files)=>{
        if(err){
            console.log(err.message)
            return 
        }
        console.log(files)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行结果:

    PS D:\Code\Study\Node\demos> node .\01-fs.js
    [
      '01-fs.js',
      'index.html',       
      'node_modules',     
      'package-lock.json',
      'package.json',     
      'style.css',
      'temp'
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    7.2 获取文件类型

    我们可以在读取文件列表的时候,获取文件的类型。

    fs.readdir('./',{withFileTypes:true},(err,files)=>{
        if(err){
            console.log(err.message)
            return 
        }
        console.log(files)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行结果:

    PS D:\Code\Study\Node\demos> node .\01-fs.js
    [
      Dirent { name: '01-fs.js', [Symbol(type)]: 1 },
      Dirent { name: 'index.html', [Symbol(type)]: 1 },
      Dirent { name: 'node_modules', [Symbol(type)]: 2 },
      Dirent { name: 'package-lock.json', [Symbol(type)]: 1 },
      Dirent { name: 'package.json', [Symbol(type)]: 1 },
      Dirent { name: 'style.css', [Symbol(type)]: 1 },
      Dirent { name: 'temp', [Symbol(type)]: 2 }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    八、fs.raname()重命名、移动文件

    oldPath 处的文件异步重命名为作为 newPath 提供的路径名。 如果 newPath 已经存在,则它将被覆盖。 如果在 newPath 中有目录,则会引发错误。 除了可能的异常之外,没有为完成回调提供任何参数。

    fs.rename(oldPath, newPath, callback)
    /**
     * oldPath <string> | <Buffer> | <URL>
     * newPath <string> | <Buffer> | <URL>
     * callback <Function>
     * err <Error>
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    8.1 重命名文件

    index.html重命名为main.html

    fs.rename('./index.html', './main.html', (err) => {
        if (err) {
            console.log(err.message)
            return
        }
        console.log('重命名成功')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行结果:

    PS E:\Code\Node\demos> node .\01-fs.js
    重命名成功
    PS E:\Code\Node\demos> ls
    
    
        目录: E:\Code\Node\demos
    
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    d-----          2022/7/4     18:43                node_modules
    da----          2022/7/4     17:33                temp
    -a----          2022/7/4     19:48           6210 01-fs.js
    -a----          2022/7/4     16:23             27 main.html         (*)
    -a----          2022/7/4     16:58           1455 package-lock.json
    -a----          2022/7/4     16:57             55 package.json
    -a----          2022/7/4     17:05             18 style.css
    -a----          2022/7/4     19:40             12 test.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    8.2 移动文件

    ./main.html移动到./temp/main.html

    fs.rename('./main.html', './temp/main.html', (err) => {
        if (err) {
            console.log(err.message)
            return
        }
        console.log('移动文件成功')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行结果:

    PS E:\Code\Node\demos> node .\01-fs.js
    移动文件成功
    PS E:\Code\Node\demos> ls .\temp\     
    
    
        目录: E:\Code\Node\demos\temp
    
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    -a----          2022/7/4     16:23             27 main.html
    
    
    PS E:\Code\Node\demos>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    九、fs.unlink()删除文件

    异步地删除文件或符号链接。 除了可能的异常之外,没有为完成回调提供任何参数。

    9.1 删除文件案例

    fs.unlink('./temp/main.html', (err) => {
        if (err) {
            console.log(err.message)
            return
        }
        console.log("删除文件成功")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行结果:

    PS E:\Code\Node\demos> ls .\temp\
    
    
        目录: E:\Code\Node\demos\temp
    
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    -a----          2022/7/4     20:03              0 main.html
    
    
    PS E:\Code\Node\demos> node .\01-fs.js
    删除文件成功
    PS E:\Code\Node\demos> ls .\temp\
    PS E:\Code\Node\demos> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    十、fs.rmdir()删除文件夹

    删除指定路径的文件夹。

    语法:

    fs.rmdir(path[, options], callback)
    /**
     * path <string> | <Buffer> | <URL>
     * options <Object>
     * maxRetries <integer> 如果遇到 EBUSY、EMFILE、ENFILE、ENOTEMPTY 或 EPERM 错误,
     *           Node.js 将在每次尝试时以 retryDelay 毫秒的线性退避等待时间重试该操作。 
     *           此选项表示重试次数。 如果 recursive 选项不为 true,则忽略此选项。 默认值: 0。
     * recursive <boolean> 如果为 true,则执行递归目录删除。 在递归模式下,操作将在失败时重试。 默认值: false。 已弃用。
     * retryDelay <integer> 重试之间等待的时间(以毫秒为单位)。 如果 recursive 选项不为 true,则忽略此选项。 默认值: 100。
     * callback <Function>
     * err <Error>
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    10.1 删除空的文件夹

    删除./temp文件夹。

    fs.rmdir('./temp', (err) => {
        if (err) {
            console.log(err.message)
            return
        }
        console.log('删除空的文件夹')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码执行结果:

    PS E:\Code\Node\demos> ls .      
    
    
        目录: E:\Code\Node\demos
    
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    d-----          2022/7/4     18:43                node_modules
    da----          2022/7/4     20:03                temp
    -a----          2022/7/4     20:09           7666 01-fs.js
    -a----          2022/7/4     16:58           1455 package-lock.json
    -a----          2022/7/4     16:57             55 package.json
    -a----          2022/7/4     17:05             18 style.css
    -a----          2022/7/4     19:40             12 test.txt
    
    
    PS E:\Code\Node\demos> node .\01-fs.js
    删除空的文件夹
    PS E:\Code\Node\demos> ls
    
    
        目录: E:\Code\Node\demos
    
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    d-----          2022/7/4     18:43                node_modules
    -a----          2022/7/4     20:09           7666 01-fs.js
    -a----          2022/7/4     16:58           1455 package-lock.json
    -a----          2022/7/4     16:57             55 package.json
    -a----          2022/7/4     17:05             18 style.css
    -a----          2022/7/4     19:40             12 test.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    10.2 删除非空的文件夹

    这里使用的是同步的文件处理函数,用于递归的删除文件夹。

    function emptyDir(path) {
        const files = fs.readdirSync(path); //同步读取文件夹
        files.forEach(file => {             //删除文件夹中的所有文件/夹
            const filePath = `${path}/${file}`;
            const stats = fs.statSync(filePath);
            if (stats.isDirectory()) {
                emptyDir(filePath);
            } else {
                fs.unlinkSync(filePath);
                console.log(`删除${file}文件成功`);
            }
        });
        fs.rmdirSync(path)                  //删除文件夹
    }
    
    emptyDir('./node_modules')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    代码执行结果:

    PS E:\Code\Node\demos> node .\01-fs.js
    删除.package-lock.json文件成功
    删除dependabot.yml文件成功
    删除codeStyleConfig.xml文件成功
    删除Project.xml文件成功
    删除iconv-lite.iml文件成功
    ... ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    十一、总结

    本文总结了Node.js常用的文件操作方法,以及常见的文件处理场景。主要包括:

    1. fs.mkdir()
    2. fs.writeFile()
    3. fs.appendFile()
    4. fs.stat()
    5. fs.readFile()
    6. fs.readdir()
    7. fs.rename()
    8. fs.unlink()
    9. fs.rmdir()
  • 相关阅读:
    2023/9/13 -- C++/QT
    【力客热题HOT100】-【040】101 对称二叉树
    C#(三十二)之Windows绘图
    【docker搭建pytorch环境及常用指令】
    卡尔曼滤波器的推导
    Alpine linux desktop
    原生AJAX
    [SWPUCTF 2018]SimplePHP
    7种链游媒体宣发工具助力游戏营销-华媒舍
    CopyOnWriteArrayList 是如何保证线程安全的?
  • 原文地址:https://blog.csdn.net/weixin_43302112/article/details/125608029