异常
Error: ENOENT: no such file or directory, mkdir
at Object.mkdirSync (node:fs:1334:3)
at F:\Pre_Coding\Pre_WebStorm_Project\linux-trash-nodejs\trash.js:82:20
at Array.forEach (<anonymous>)
at copyDirectory (F:\Pre_Coding\Pre_WebStorm_Project\linux-trash-nodejs\trash.js:74:11)
at Object.<anonymous> (F:\Pre_Coding\Pre_WebStorm_Project\linux-trash-nodejs\trash.js:46:13)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
errno: -4058,
syscall: 'mkdir',
code: 'ENOENT'
}
错误代码
在Linux系统上执行此复制文件夹的代码,报上面的错:
var fs = require('fs')
var path = require('path')
/**
* 将指定src目录下的所有文件复制(剪切)到指定目标dest目录下
* @param src 源目录
* @param dest 目标目录
*/
function copyDirectory(src, dest) {
var files = fs.readdirSync(src);
files.forEach((item, index) => {
var itemPath = path.join(src, item);
var itemStat = fs.statSync(itemPath);// 获取文件信息
var savedPath = path.join(dest, itemPath.replace(src, ''));
var savedDir = savedPath.substring(0, savedPath.lastIndexOf('\\'));
if (itemStat.isFile()) {
// 如果目录不存在则进行创建
if (!fs.existsSync(savedDir)) {
fs.mkdirSync(savedDir, {
recursive: true});
}
// 写入到新目录下
var data = fs.readFileSync(itemPath);
fs.writeFileSync(savedPath, data);
// 并且删除原文件
fs.unlinkSync(itemPath);
} else if (itemStat.isDirectory()) {
copyDirectory(itemPath, path.join(savedDir, item));
}
});
// 并且删除原目录
fs.rmdirSync(src);
}
// copyDirectory('D:\\NodeJs\\node-demo\\abc', 'G:\\Trash\\files\\abc');
copyDirectory('/root/home/hello', '/root/home/Trash');
原因
这份代码在Windows系统环境下并不会报错,错误提示no such file or directory, mkdir
说没有这个目录,即创建目录时传入的目录路径不对。
但在Windows系统下运行该代码是正确的,怎么到Linux系统就不行了,这才是导致这个错误发生的根本原因。
问题就出现在var savedDir = savedPath.substring(0, savedPath.lastIndexOf('\\'));
这行代码上,获取要保存的目录,如G:\Trash\files\abc\a.txt
经过该行代码后返回G:\Trash\files\abc
,是使用\\
分隔符进行提取的,但是在Linux系统上的路径分隔符是\
,这才是问题的关键。
因为Windows系统的路径分隔符是\
,而Linux系统的路径分隔符是/
。
解决
我们可以根据是什么系统就用什么路径分隔符,通过path
模块的sep
属性来获取当前使用系统的路径分隔符,即path.sep
。如果是Windows系统则输出\
,如果是Linux系统则输出/
。
正确代码
var fs = require('fs')
var path = require('path')
/**
* 将指定src目录下的所有文件复制(剪切)到指定目标dest目录下
* @param src 源目录
* @param dest 目标目录
*/
function copyDirectory(src, dest) {
var files = fs.readdirSync(src);
files.forEach((item, index) => {
var itemPath = path.join(src, item);
var itemStat = fs.statSync(itemPath);// 获取文件信息
var savedPath = path.join(dest, itemPath.replace(src, ''));
var savedDir = savedPath.substring(0, savedPath.lastIndexOf(path.sep));// 根据系统获取分隔符
if (itemStat.isFile()) {
// 如果目录不存在则进行创建
if (!fs.existsSync(savedDir)) {
fs.mkdirSync(savedDir, {
recursive: true});
}
// 写入到新目录下
var data = fs.readFileSync(itemPath);
fs.writeFileSync(savedPath, data);
// 并且删除原文件
fs.unlinkSync(itemPath);
} else if (itemStat.isDirectory()) {
copyDirectory(itemPath, path.join(savedDir, item));
}
});
// 并且删除原目录
fs.rmdirSync(src);
}
// copyDirectory('D:\\NodeJs\\node-demo\\abc', 'G:\\Trash\\files\\abc');
copyDirectory('/root/home/hello', '/root/home/Trash');