import fs from "fs" import { isEmpty } from "lodash"; import path from "path"; const fspromises = fs.promises; /** * 判断文件或目录是否存在 * @param {*} path 文件或目录的路径 * @returns true表示存在,false表示不存在 */ export async function CheckFileOrDirExist(path) { try { await fspromises.access(path); return true; // 文件或目录存在 } catch (error) { return false; // 文件或目录不存在 } } // 检查文件夹是不是存在,不存在的话,创建 export async function CheckFolderExistsOrCreate(folderPath) { try { if (!(await CheckFileOrDirExist(folderPath))) { await fspromises.mkdir(folderPath, { recursive: true }); } } catch (error) { throw new Error(error); } } /** * 拼接两个地址,返回拼接后的地址 * @param {*} rootPath 根目录的消息 * @param {*} subPath 子目录的消息 * @returns */ export function JoinPath(rootPath, subPath) { // 判断第二个地址是不是存在,不存在返回null,存在返回拼接后的地址 if (subPath && !isEmpty(subPath)) { return path.resolve(rootPath, subPath) } else { return null } } /** * 拷贝一个文件或者是文件夹到指定的目标地址 * @param {*} source 源文件或文件夹地址 * @param {*} target 目标文件或文件夹地址 * @param {*} checkParent 是否检查父文件夹是否存在,不存在的话创建,默认false,不检查,不存在直接创建 */ export async function CopyFileOrFolder(source, target, checkParent = false) { try { // 判断源文件或文件夹是不是存在 if (!(await CheckFileOrDirExist(source))) { throw new Error(`源文件或文件夹不存在: ${source}`); } // 判断父文件夹是否存在,不存在创建 const parent_path = path.dirname(target); let parentIsExist = await CheckFileOrDirExist(parent_path); if (!parentIsExist) { if (checkParent) { throw new Error(`目的文件或文件夹的父文件夹不存在: ${parent_path}`); } else { await fspromises.mkdir(parent_path, { recursive: true }); } } // 判断是不是文件夹 const isDirectory = await IsDirectory(source); // 复制文件夹的逻辑 async function copyDirectory(source, target) { // 创建目标文件夹 await fspromises.mkdir(target, { recursive: true }); let entries = await fspromises.readdir(source, { withFileTypes: true }); for (let entry of entries) { let srcPath = path.join(source, entry.name); let tgtPath = path.join(target, entry.name); if (entry.isDirectory()) { await copyDirectory(srcPath, tgtPath); } else { await fspromises.copyFile(srcPath, tgtPath); } } } if (isDirectory) { // 创建目标文件夹 await copyDirectory(source, target); } else { // 复制文件 await fspromises.copyFile(source, target); } } catch (error) { throw error; } } /** * 判断一个文件地址是不是文件夹 * @param {*} path 输入的文件地址 * @returns true 是 false 不是 */ export async function IsDirectory(path) { try { const stat = await fspromises.stat(path); return stat.isDirectory(); } catch (error) { throw new Error(`获取文件夹信息失败: ${path}`); } } /** * 将文件或者是文件夹备份到指定的文职 * @param {*} source_path 源文件/文件夹地址 * @param {*} target_path 目标文件/文件夹地址 */ export async function BackupFileOrFolder(source_path, target_path) { try { // 判断父文件夹是否存在,不存在创建 const parent_path = path.dirname(target_path); if (!(await CheckFileOrDirExist(parent_path))) { await fspromises.mkdir(parent_path, { recursive: true }); } // 判断是不是文件夹 const isDirectory = await IsDirectory(source_path); if (isDirectory) { // 复制文件夹 await fspromises.rename(source_path, target_path); } else { // 复制文件 await fspromises.copyFile(source, target); } } catch (error) { throw new Error(error); } } /** * 获取指定的文件夹下面的所有的指定的拓展名的文件 * @param {*} folderPath 文件夹地址 * @param {*} extensions 拓展地址 * @returns 返回文件中指定的后缀文件地址(绝对地址) */ export async function GetFilesWithExtensions(folderPath, extensions) { try { // 判断当前是不是文件夹 if (!(await IsDirectory(folderPath))) { throw new Error("输入的不是有效的文件夹地址") } let entries = await fspromises.readdir(folderPath, { withFileTypes: true }); let files = []; // 使用Promise.all来并行处理所有的stat调用 const fileStats = await Promise.all(entries.map(async (entry) => { const entryPath = path.join(folderPath, entry.name); if (entry.isFile()) { return { name: entry.name, path: entryPath, isFile: true, }; } else { return { isFile: false, }; } })); // 过滤出文件并且满足扩展名要求的文件 files = fileStats.filter(fileStat => fileStat.isFile && extensions.includes(path.extname(fileStat.name).toLowerCase())); // 对files数组进行排序,基于文件名 files.sort((a, b) => a.name.localeCompare(b.name)); // 返回文件名数组(完整的) return files.map(fileStat => path.join(folderPath, fileStat.name)); } catch (error) { throw new Error(error); } }