一、复制文件或文件夹
1.同步复制
const fs = require('fs'); //文件模块
const path = require('path'); //系统路径模块
/**
* 同步复制文件或文件夹
* @param {String} fromPath 源始路径,参数可以是文件或文件夹
* @param {String} toPath 目标路径,参数可以是文件或文件夹
*/
function copyFileSync(fromPath, toPath, cb) {
try {
fs.accessSync(toPath);
} catch (err) {
fs.mkdirSync(toPath)
}
const filenames = fs.readdirSync(fromPath);
filenames.forEach((filename) => {
const newFromPath = path.join(fromPath, filename);
const newToPath = path.join(toPath, filename);
const stat = fs.statSync(newFromPath);
if (stat.isFile()) {
fs.copyFileSync(newFromPath, newToPath);
}
if (stat.isDirectory()) {
copyFileSync(newFromPath, newToPath, cb);
}
})
}
应用示例:复制文件夹a到b
const path = require('path'); //系统路径模块
const pathA = path.join(__dirname, './a');
const pathB = path.join(__dirname, './b');
copyFileSync(pathA, pathB);
2.异步复制
/**
* 异步复制文件或文件夹
* @param {*} fromPath 源始路径,参数可以是文件或文件夹
* @param {*} toPath 目标路径,参数可以是文件或文件夹
*/
function copyFile(fromPath, toPath) {
return new Promise((resolve, reject) => {
fs.access(fromPath, err => {
if (err) reject(err)
fs.stat(fromPath, (err, stats) => {
//如果是文件
if (stats.isFile()) {
fs.copyFile(fromPath, toPath, (err) => {
err ? reject(err) : resolve();
});
} else {
fs.access(toPath, err => {
// 如果不存在则创建
new Promise((resv, rejt) => {
err ? fs.mkdir(toPath, err => (err ? rejt(err) : resv())) : resv();
}).then(() => {
fs.readdir(fromPath, (err, filenames) => {
if (err) reject(err)
Promise.all(filenames.map(filename => {
return new Promise((res, rej) => {
let newFromPath = path.join(fromPath, filename)
let newToPath = path.join(toPath, filename)
fs.stat(newFromPath, (err, stats) => {
if (err) rej(err)
//如果是文件
if (stats.isFile()) {
fs.copyFile(newFromPath, newToPath, (err) => {
err ? rej(err) : res();
});
} else {
//如果是目录递归调用
res(copyFile(newFromPath, newToPath))
}
})
});
})).then(() => {
resolve()
}).catch(reject);
});
}).catch(reject);
});
}
});
})
})
}
应用示例:复制文件夹a到b
const path = require('path'); //系统路径模块
const pathA = path.join(__dirname, './a');
const pathB = path.join(__dirname, './b');
copyFile(pathA, pathB).then((resolve) => {
console.log('复制成功');
}).catch(e => {
console.log(e)
});
二、删除文件或文件夹
1.同步删除
const fs = require('fs'); //文件模块
const path = require('path'); //系统路径模块
**
* 同步删除文件或文件夹
* @param {String} filePath 文件路径,参数可以是文件或文件夹
*/
function deleteFileSync(filePath) {
// 检测文件是否存在
if (fs.existsSync(filePath)) {
// 检测文件是目录
if (fs.statSync(filePath).isDirectory()) {
// 获取目录内所有文件名
const filenames = fs.readdirSync(filePath);
filenames.forEach((filename) => {
const currentPath = path.join(filePath, filename);
if (fs.statSync(currentPath).isDirectory()) {
deleteFileSync(currentPath);
} else {
fs.unlinkSync(currentPath);
}
});
fs.rmdirSync(filePath);
} else {
fs.unlinkSync(filePath);
}
}
}
应用示例:删除文件夹a
const path = require('path'); //系统路径模块
const pathA = path.join(__dirname, './a');
delFile(pathA);
2.异步删除
const fs = require('fs'); //文件模块
const path = require('path'); //系统路径模块
/**
* 异步删除文件或文件夹
* @param {String} filePath 文件路径,参数可以是文件或文件夹
*/
function deleteFile(filePath) {
return new Promise((resolve, reject) => {
fs.access(filePath, err => {
if (err) reject(err)
fs.stat(filePath, (err, stats) => {
if (err) reject(err)
if (stats.isFile()) {
fs.unlink(filePath, err => {
if (err) reject(err)
resolve()
})
} else {
fs.readdir(filePath, (err, filenames) => {
if (err) reject(err)
Promise.all(filenames.map(filename => {
return new Promise((res, rej) => {
let currentPath= path.join(filePath, filename)
fs.stat(currentPath, (err, stats) => {
if (err) rej(err)
//如果是文件
if (stats.isFile()) {
fs.unlink(currentPath, err => {
if (err) rej(err)
res()
})
} else {
//如果是目录递归调用
res(deleteFile(currentPath))
}
})
})
})).then(() => {
fs.rmdir(filePath, err => {
if (err) reject(err)
resolve()
})
}).catch(reject)
})
}
});
})
})
}
应用示例:删除文件夹a
const path = require('path'); //系统路径模块
const pathA = path.join(__dirname, './a');
deleteFile(pathA).then((resolve) => {
console.log('删除成功');
}).catch(e => {
console.log(e)
});
3.异步删除(拆分成两个方法)
const fs = require('fs'); //文件模块
const path = require('path'); //系统路径模块
function deleteDirectory(dirPath){
return new Promise((resolve,reject)=>{
fs.access(dirPath,err=>{
if(err)reject(err)
fs.readdir(dirPath,(err,files)=>{
if(err)reject(err)
Promise.all(files.map(file=>{
return deleteFile(dirPath,file)
})).then(()=>{
fs.rmdir(dirPath,err=>{
if(err)reject(err)
resolve()
})
}).catch(reject)
})
})
})
}
function deleteFile(dirPath,file){
return new Promise((resolve,reject)=>{
let filePath = path.join(dirPath,file)
fs.stat(filePath,(err,stats)=>{
if(err)reject(err)
if(stats.isFile()){
fs.unlink(filePath,err=>{
if(err)reject(err)
resolve()
})
}else{
//返回deleteDirectory在all中递归调用
resolve(deleteDirectory(filePath))
}
})
})
}
应用示例:删除文件夹a
const path = require('path'); //系统路径模块
const pathA = path.join(__dirname, './a');
deleteDirectory(pathA).then((resolve) => {
console.log('删除成功');
}).catch(e => {
console.log(e)
});
三、替换文件内容
1.同步替换
/**
* 同步替换文件内容
* @param {String} filePath 文件路径
* @param {*} oldContent 原始内容
* @param {*} newContent 新内容
* @param {String} suffix 后缀名,多个中间以|分隔
*/
function replaceFileSync(filePath, oldContent, newContent, suffix) {
// 文件存在且类型是文件
if (fs.existsSync(filePath) && fs.statSync(filePath).isFile() && oldContent && newContent) {
// 获取路径后缀并去除前面的点
let ext = path.extname(filePath);
ext = ext ? ext.slice(1) : '';
// 如果没有指定后缀,或者指定了后缀且匹配路径后缀,执行替换
if (!suffix || (suffix.includes(ext))) {
const data = fs.readFileSync(filePath); // 读取文件
const content = data.toString().replace(oldContent, newContent); // 将原始内容替换为新内容
fs.writeFileSync(filePath, content); // 写入文件
}
}
}
应用示例:替换文件夹a内容1111为2222
const path = require('path'); //系统路径模块
const pathA = path.join(__dirname, './a');
replaceFileSync(pathA, '1111', '2222', 'html|txt');