经过我仔细脑补执行方法,递归复制文件夹 我的理解就是“套娃执行”。
核心代码:
++count == files.length && cb && cb()
一个文件拷贝完成+1,每一层套娃文件拷贝完 ==files.length才会执行返回事件,遇文件夹会将事件传递给下一层套娃去判断是否执行+1。
let fs = require('fs');
let path = require('path');
//递归拷贝文件
function copyFile(srcPath, tarPath, cb) {
var rs = fs.createReadStream(srcPath)
rs.on('error', function (err) {
if (err) {
console.log('read error', srcPath)
}
cb && cb(err)
})
var ws = fs.createWriteStream(tarPath)
ws.on('error', function (err) {
if (err) {
console.log('write error', tarPath)
}
cb && cb(err)
})
ws.on('close', function (ex) {
cb && cb(ex)
})
rs.pipe(ws)
}
//递归拷贝文件夹
function copyDir(srcDir, tarDir, cb) {
fs.readdir(srcDir, function (err, files) {
var count = 0
var checkEnd = function () {
++count == files.length && cb && cb()
}
if (err) {
checkEnd()
return
}
!fs.existsSync(tarDir) && fs.mkdirSync(tarDir);
console.log("copyDir -> tarDir", tarDir)
files.forEach(function (file) {
var srcPath = path.join(srcDir, file)
var tarPath = path.join(tarDir, file)
fs.stat(srcPath, function (err, stats) {
if (stats.isDirectory()) {
copyDir(srcPath, tarPath, checkEnd)
} else {
copyFile(srcPath, tarPath, checkEnd)
}
})
})
//为空时直接回调
files.length === 0 && cb && cb()
})
}
删除文件夹并返回事件递归方法类似:
//递归删除文件夹
function delDir(filePath, callback) {
// 先判断当前filePath的类型(文件还是文件夹,如果是文件直接删除, 如果是文件夹, 去取当前文件夹下的内容, 拿到每一个递归)
fs.stat(filePath, function (err, stat) {
if (err) {
callback && callback(err);
return;
}
if (stat.isFile()) {
fs.unlink(filePath, callback)
} else {
fs.readdir(filePath, function (err, data) {
if (err) return console.log(err)
let dirs = data.map(dir => path.join(filePath, dir))
let index = 0
!(function next() {
// 此处递归删除掉所有子文件 后删除当前 文件夹
if (index === dirs.length) {
fs.rmdir(filePath, callback)
} else {
delDir(dirs[index++], next)
}
})()
})
}
})
}
Comments | NOTHING