循环创建文件夹

创建文件夹

目录结构

|— 20-mkdir.js

1
2
3
4
5
6
7
8
const fs = require("fs");
const path = require("path");
fs.mkdir(path.join(__dirname,"demo1"),(err) => {
console.log(err)
});
fs.mkdir(path.join(__dirname,"./demo2"),(err) => {
console.log(err)
});

执行20-mkdir.js

1
2
3
$ node 20-mkdir.js
null
null

目录结构变为

|— 20-mkdir.js

|— demo1

|— demo2


报错

什么情况下会报错呢?

文件夹已经存在

目录结构

|— 20-mkdir.js

|— demo1

|— demo2

这里的意思是原本就已经存在demo1和demo2,我们试着再创建一下

同样执行20-mkdir.js

1
2
3
4
5
6
7
8
9
10
11
$ node 20-mkdir.js
{ Error: EEXIST: file already exists, mkdir '/Users/melody0z/github/nodejs/second/demo1'
errno: -17,
code: 'EEXIST',
syscall: 'mkdir',
path: '/Users/melody0z/github/nodejs/second/demo1' }
{ Error: EEXIST: file already exists, mkdir '/Users/melody0z/github/nodejs/second/demo2'
errno: -17,
code: 'EEXIST',
syscall: 'mkdir',
path: '/Users/melody0z/github/nodejs/second/demo2' }

报错信息为Error: EEXIST: file already exists说文件夹已经存在。

不存在的文件夹

20-mkdir.js

1
2
3
4
5
6
7
8
9
10
11
const fs = require("fs");
const path = require("path");
- fs.mkdir(path.join(__dirname,"demo1"),(err) => {
- console.log(err)
- });
- fs.mkdir(path.join(__dirname,"./demo2"),(err) => {
- console.log(err)
- });
+ fs.mkdir(path.join(__dirname,"./test/demo3"),(err) => {
+ console.log(err);
+ });

执行20-mkdir.js

1
2
3
4
5
6
$ node 20-mkdir.js
{ Error: ENOENT: no such file or directory, mkdir '/Users/melody0z/github/nodejs/second/test/demo3'
errno: -2,
code: 'ENOENT',
syscall: 'mkdir',
path: '/Users/melody0z/github/nodejs/second/test/demo3' }

报错信息Error: ENOENT: no such file or directory不存在的文件夹,因为我们并没有test文件夹,所以它不会帮我们创建,就直接报错。

创建层级目录

我们先来创建一个模块

mkdirs.js

1
2
function mkdirs(pathname,callback){}
module.exports = mkdirs;

在21-mkdirs.js中引入

1
2
3
const fs = require("fs");
const path = require("path");
const mkdirs = require("./mkdirs");

这是大体的骨架,然后我们来完善mkdirs.js模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
+ //我们需要文件操作,文件操作就需要引入fs和path
+ const fs = require("fs");
+ const path = require("path");
function mkdirs(pathname, callback) {
+ //1.判断传入的是否是绝对路径
+ pathname = path.isAbsolute(pathname)
+ ? pathname
+ : path.join(__dirname, pathname);
+ //2.获取想要创建的部分
+ // /Users/melody0z/github/nodejs/second/test/demo3
+ // test文件夹和demo3文件夹需要创建,我们需要获取
+ // dirname 是/Users/melody0z/github/nodejs/second
+ pathname = pathname.replace(__dirname,"");
+ console.log(pathname);
}
module.exports = mkdirs;

写到这里我们来测试一下,在21-mkdirs.js中

1
2
3
4
5
6
const fs = require("fs");
const path = require("path");
const mkdirs = require("./mkdirs");
mkdirs("test/demo3");
mkdirs("/Users/melody0z/github/nodejs/second/test/demo3")

执行

1
2
3
$ node 21-mkdirs.js
/test/demo3
/test/demo3

是我们想要的结果,我们得到了test和demo3

然而我们还有一种方法,那就是path模块自带的path.relative()方法

mkdirs.js中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const fs = require("fs");
const path = require("path");
function mkdirs(pathname, callback) {
//1.判断传入的是否是绝对路径
pathname = path.isAbsolute(pathname)
? pathname
: path.join(__dirname, pathname);
//2.获取想要创建的部分
// /Users/melody0z/github/nodejs/second/test/demo3
// test文件夹和demo3文件夹需要创建,我们需要获取
// dirname 是/Users/melody0z/github/nodejs/second
- //pathname = pathname.replace(__dirname,"");
+ pathname = path.relative(__dirname,pathname);
console.log(pathname);
}
module.exports = mkdirs;

其余不变,我们再来执行21-mkdirs.js

1
2
3
$ node 21-mkdirs.js
test/demo3
test/demo3

同样也能得到test和demo3。

以上两种方法的区别仅仅是多一个少一个/

好了,我们用第二种方法接着往下写

mkdirs.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const fs = require("fs");
const path = require("path");
function mkdirs(pathname, callback) {
//1.判断传入的是否是绝对路径
pathname = path.isAbsolute(pathname)
? pathname
: path.join(__dirname, pathname);
//2.获取想要创建的部分
// /Users/melody0z/github/nodejs/second/test/demo3
// test文件夹和demo3文件夹需要创建,我们需要获取
// dirname 是/Users/melody0z/github/nodejs/second
let relativePath = path.relative(__dirname,pathname);
let folders = relativePath.split(path.sep);
console.log(folders);
}
module.exports = mkdirs;

注意14行let folders = relativePath.split(path.sep);中不能写成let folders = relativePath.split("/");因为windows和POSIX平台上是不同的,需要用path.sep来代替。

然后我们执行一下21-mkdirs.js来测试一下

1
2
3
$ node 21-mkdirs.js
[ 'test', 'demo3' ]
[ 'test', 'demo3' ]

good!是我们想要的结果。

我们继续写

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
const fs = require("fs");
const path = require("path");
function mkdirs(pathname, callback) {
//1.判断传入的是否是绝对路径
pathname = path.isAbsolute(pathname)
? pathname
: path.join(__dirname, pathname);
//2.获取想要创建的部分
// /Users/melody0z/github/nodejs/second/test/demo3
// test文件夹和demo3文件夹需要创建,我们需要获取
// dirname 是/Users/melody0z/github/nodejs/second
let relativePath = path.relative(__dirname,pathname);
let folders = relativePath.split(path.sep);
+ //3.遍历,由于遍历是同步的(文件夹需要有顺序),创建文件夹也需要同步
+ //同步的话就需要用try...catch来捕获错误
+ try{
+ folders.forEach(folder => {
+ fs.mkdirSync(path.join(__dirname,folder));
+ });
+ callback && callback(null);
+ }catch (error){
+ callback && callback(error)
+ }
}
module.exports = mkdirs;

21-mkdirs.js

1
2
3
4
5
const fs = require("fs");
const path = require("path");
const mkdirs = require("./mkdirs");
mkdirs(path.join(__dirname,"test/demo3"));

我们来执行一下21-mkdirs.js

目录结构发生了变化

|— 21-mkdirs.js

|— mkdirs.js

|— test

|— demo3

我们发现demo3并没有在test文件夹里面,所以我们还需要修改

mkdirs.js

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
const fs = require("fs");
const path = require("path");
function mkdirs(pathname, callback) {
//1.判断传入的是否是绝对路径
pathname = path.isAbsolute(pathname)
? pathname
: path.join(__dirname, pathname);
//2.获取想要创建的部分
// /Users/melody0z/github/nodejs/second/test/demo3
// test文件夹和demo3文件夹需要创建,我们需要获取
// dirname 是/Users/melody0z/github/nodejs/second
let relativePath = path.relative(__dirname,pathname);
let folders = relativePath.split(path.sep);
+ let pre = "";
try{
folders.forEach(folder => {
- fs.mkdirSync(path.join(__dirname,folder));
+ fs.mkdirSync(path.join(__dirname,pre,folder));
+ pre = path.join(pre,folder);
});
callback && callback(null);
}catch (error){
callback && callback(error)
}
}
module.exports = mkdirs;

我们再来执行21-mkdirs.js

目录结构

|— 21-mkdirs.js

|— mkdirs.js

|— test

  |— demo3

这样就打成我们的目标了

注意点

我们更改一下目录结构

|— module

  |— mkdirs.js

|— 21-mkdirs.js

再来执行21-mkdirs.js就会报错,说文件夹已存在,原因就在于mkdirs.js模块里的__dirname;

__dirname是相对于mkdirs.js模块的路径,而我们需要的是谁引用了mkdirs.js模块,路径就相对于谁,这里需要使用module.parent.

module/mkdirs.js

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
34
35
36
37
38
39
40
const fs = require("fs");
const path = require("path");
function mkdirs(pathname, callback) {
const filename = module.parent.filename;
const root = path.dirname(filename);
//1.判断传入的是否是绝对路径
pathname = path.isAbsolute(pathname)
? pathname
: path.join(root, pathname);
//2.获取想要创建的部分
// /Users/melody0z/github/nodejs/second/test/demo3
// test文件夹和demo3文件夹需要创建,我们需要获取
// __dirname 是/Users/melody0z/github/nodejs/second
//pathname = pathname.replace(__dirname,"");
//注意:这里的__dirname有问题,应该是谁调用这个模块,__dirname就是就是这个文件的路径
let relativePath = path.relative(root,pathname);
let folders = relativePath.split(path.sep);
let pre = "";
try{
folders.forEach(folder => {
try{
//检测文件夹状态,文件夹不存在跳到catch里面去创建
fs.statSync(path.join(root,pre,folder));
}catch (error){
fs.mkdirSync(path.join(root,pre,folder));
}
pre = path.join(pre,folder);
});
callback && callback(null);
}catch (error){
callback && callback(error)
}
}
module.exports = mkdirs;

21-mkdirs.js

1
2
3
4
5
6
7
8
9
10
const fs = require("fs");
const path = require("path");
const mkdirs = require("./module/mkdirs");
mkdirs(path.join(__dirname,"test/demo3/demo4"),(err) => {
console.log(err)
});
mkdirs(path.join(__dirname,"test/demo3/demo5"),(err) => {
console.log(err)
});

我们执行后,创建的目录如下

|— test

  |— demo3

    |— demo4

    |— demo5


本文结束,感谢阅读。

本文作者:melody0z
本文链接:https://melodyvoid/Node/cycle-creation-folder.html
欢迎转载,转载请注明文本链接

坚持原创技术分享,您的支持将鼓励我继续创作!