目录操作

除了对文件进行操作的方法,fs 模块还提供了一系列对目录(文件夹)进行操作的方法,下面分别介绍。

创建目录

创建目录可以使用 mkdir()mkdirSync() 方法实现,它们分别用来异步和同步创建目录,语法格式如下:

fs.mkdir(path[, options], callback)
fs.mkdirSync(path[, options])
  • path:要被创建的目录的完整路径及目录名。

  • options:指定目录的权限,默认为 0777(表示任何人可读可写该目录)。

  • callback:指定创建目录操作完毕时调用的回调函数,该回调函数中只有一个参数,参数值为创建目录操作失败时触发的错误对象。

【例7.8】批量创建文件并放到指定的文件夹中。(实例位置:资源包\源码\07\08)

WebStorm 中新建一个项目文件夹,该文件夹中添加一个 b.txt 文件,该文件中包含五首古诗名称。然后新建 js.js 文件,该文件中需要先判断 demo 文件夹是否存在。如果不存在,则使用 mkdir() 方法创建该文件夹;如果存在,则读取 b.txt 文件的内容,并根据读取到的内容在 demo 文件夹中批量创建文件。代码如下:

var fs = require("fs")
//检查demo文件夹是否存在
fs.access("demo", fs.constants.F_OK, function (err) {
     if (err) {                                           //如果不存在,则创建demo文件夹,反之则继续下一步
          fs.mkdir("demo", function (err) {
               if(err)
                     console.log("糟糕,创建文件夹时出错了")
          })
     }
     //读取b.txt文件,该文件中保存了要批量创建的文件的名称
     var data = fs.readFileSync("b.txt", "utf8").split("\r")
     //逐个创建文件
     for (var i = 0; i < data.length; i++) {
          var title = data[i].replace("\n", "")           //去掉读取到的内容中的换行符
          fs.writeFile("demo\\" + title + ".txt", "", function (err) {
               if(err)
                     console.log("创建文件失败")
          })
     }
})

运行程序,打开项目文件夹,可以看到项目文件夹中新建了 demo 文件夹,并且 demo 文件夹中新建了 5 个文本文件,如图7.16所示。

这里需要注意的是,创建目录时需要一级一级地创建,而不是直接创建多级目录。例如,要创建目录 “第1章\第1节”,首先需要保证 “第1章” 目录存在,然后才能创建目录 “第1节”,例如,下面的代码是错误的:

const fs = require("fs")
fs.mkdir("第1章\\第1节",function(err){
     console.log("创建文件夹失败")
     console.log(err)
})

此时就会显示错误信息。正确方法应该是判断 “第1章” 目录是否存在,如果存在,可以直接创建 “第1章\第1节”;否则,先创建目录 “第1章”,然后创建目录 “第1章\第1节”。代码如下:

const fs = require("fs")
fs.access("第1章", fs.constructor.F_OK, function (err) {
     if (err) {
          fs.mkdirSync("第1章")                      //如果“第1章”不存在,那么创建“第1章”
     }
     fs.mkdir("第1章\\第1节", function (err) {
          if (err) {
               console.log("该目录已存在")           //如果出现错误,表示该目录已经存在
          }
          else {
               console.log("创建目录成功")
          }
     })
})

运行程序,即可查看创建好的多级目录。

读取目录

fs 模块中,可以使用 readdir() 方法或者 readdirSync() 方法读取目录,其中,readdir() 方法用来异步读取目录,readdirSync() 方法用来同步读取目录。由于在实际应用中,通常都使用默认的 readdir() 方法异步读取,因此这里主要讲解 readdir() 方法的使用,其语法格式如下:

fs.readdir(path[, options], callback)
  • path:文件名或者文件描述符。

  • options:可选参数,可以为如下值。

    • encoding:编码方式。

    • flag:文件系统标志。

    • signal:允许中止正在进行的读取文件操作。

  • callback:回调函数,在回调函数中有两个参数,具体如下。

    • err:出现错误时的错误信息。

    • data:调用成功时的返回值。

例如,可以使用下面代码读取 ..\test 文件夹中的内容:

const fs = require("fs")
fs.readdir('..\\test', function (err, files) {
     if (err) console.log('读取文件夹操作失败。');
     else console.log(files);
});

上面代码中使用了相对路径 ..\test,使用 readdir 方法时,也可以使用绝对路径,如 C:\test

删除空目录

fs 模块中,可以使用 rmdir() 方法或者 rmdirSync() 方法删除空目录,其中,rmdir() 方法用来异步删除空目录,rmdirSync() 方法用来同步删除空目录。由于在实际应用中,通常都使用默认的 rmdir() 方法进行异步删除,因此这里主要讲解 rmdir() 方法的使用,语法格式如下:

fs.rmdir(path[, options], callback)
  • path:用于指定要被删除目录的完整路径以及目录名。

  • options:可选参数,可以为如下值。

    • recursive:如果为 true,则执行递归目录删除操作。在递归模式下,操作将在失败时重试。默认值为 false

    • retryDelay:重试之间等待的时间(以毫秒为单位)。如果 recursive 选项不为 true,则忽略此选项。默认值为 100。

    • maxRetries:表示重试次数,如果遇到 EBUSYEMFILEENFILEENOTEMPTYEPERM 错误,Node.js 将在每次尝试时,以 retryDelay 毫秒的线性退避等待时间重试该操作。如果 recursive 选项不为 true,则忽略此选项。默认值为 0。

  • callback:用于指定删除目录操作完毕时调用的回调函数。

例如,下面代码可以删除空的 demo 文件夹,如果 demo 文件夹不为空,则不能删除。代码如下:

const fs = require("fs")
fs.rmdir('./demo', function (err) {
     if (err){
          console.log('删除空目录操作失败。');
          console.log(err)
     }
     else console.log('删除空目录操作成功。');
});

rmdir() 方法仅用于删除空文件夹,如果所指定的文件夹不是空文件夹,就会出现错误。

查看目录信息

fs 模块中,可以使用 stat() 方法或者 lstat() 方法查看目录或文件信息,但如果是查看链接文件的信息,就必须使用 lstat() 方法。stat() 方法或者 lstat() 方法的语法格式如下:

stat(path,callback)
lstat(path,callback)

其中,path 参数用于指定要被查看的目录或文件的完整路径(包括目录名或者文件名);callback 参数用于指定查看目录或文件操作完毕时调用的回调函数,该回调函数中包括两个参数,即 errstatserr 表示出现错误时的错误信息,stats 为一个对象,表示文件的相关属性。

【例7.9】查看指定文件夹的详细信息。(实例位置:资源包\源码\07\09)

在 WebStorm 中创建 js.js 文件,该文件中使用 stat 方法获取 demo 文件夹的详细信息。代码如下:

const fs = require("fs")
fs.stat("demo", function (err, stats) {
     if(err){
          console.log("获取文件夹信息失败")
     }
     else{
          console.log(stats)
     }
})

程序运行效果如图7.20所示。

image 2024 04 11 21 55 37 217
Figure 1. 图7.20 查看目录信息

从返回的结果中可以看到很多属性信息,关于这些属性信息的说明,如表7.3所示。

image 2024 04 11 21 58 27 814
Figure 2. 表7.3 目录的属性信息
image 2024 04 11 21 58 55 813
Figure 3. 表7.4 stat对象的相关方法

stat 对象包括一系列方法,具体如表7.4所示。例如,判断 b.txt 是否为文件,以及是否为目录,其代码如下:

const fs = require("fs")
fs.stat("b.txt", function (err, stats) {
     console.log("是否为文件", stats.isFile())
     console.log("是否为文件夹/目录", stats.isDirectory())
})

获取目录的绝对路径

fs 模块中,可以使用 realpath() 方法或 realpathSync() 方法获取指定目录的绝对路径,其中,realpath() 方法用于异步操作,realpathSync() 方法用于同步操作。由于在实际应用中,通常都使用默认的 realpath() 方法进行异步操作,因此这里主要讲解 realpath() 方法的使用,其语法格式如下:

fs.realpath(path[, options], callback)
  • path:路径,可以为字符串或者 url

  • options:一般为 encoding,用于指定编码格式,默认为 utf8

  • callback:回调函数,该回调函数中有两个参数,具体如下。

    • err:发生错误时的错误信息。

    • resolvedPath:绝对路径。

例如,下面代码用来获取 b.txt 文件的绝对路径:

const fs = require("fs")
fs.realpath('b.txt', function (err,resolvedPath) {
     if (err){
          console.log('获取绝对路径失败');
          console.log(err)
     }
     else console.log(resolvedPath);
});