import { readdirSync, statSync, writeFileSync, PathLike, existsSync, unlinkSync, mkdirSync, rmdirSync, createReadStream, accessSync, createWriteStream, constants, readFileSync, copyFileSync } from 'fs' import { join } from 'path' import { checkFileExistsAndCreateType } from './enum' import { Error, error, Warn, warn } from './tip-style' const pathList: Set = new Set() /** * @name 读取目录下所有文件 * @export * @param {string} entry 目录名称 */ export function readDirPath(entry: string): Set { const dirInfo = readdirSync(entry); for (let item of dirInfo) { const location = join(entry, item); const info = statSync(location); if (info.isDirectory()) { readDirPath(location); } else { pathList.add(location) } } return pathList } /** * @name 读取指定目录的文件(不进行深度遍历,只获取根目录) * @export * @param {*} entry * @returns */ export function readDirGetFile(entry: string) { const dirInfo = readdirSync(entry); return dirInfo } /** * @name 解析json文件(数组) * @export * @param {Array} arr * @returns */ export function parseJsonFiles(arr: Set) { const result = [] for (let item of arr) { const data = parseJsonFile(item); result.push(data) } return result } /** * @name 解析单个文件json * @export * @param {PathLike} file * @returns */ export function parseJsonFile(file: string) { try { const data = readFileSync(file, 'utf8'); return JSON.parse(data) } catch (error) { return } } /** * @name 删除文件夹 * @export * @param {string} entry */ export function deleteFolderRecursive(entry: string) { let files = []; // 判断给定的路径是否存在 if (existsSync(entry)) { // 返回文件和子目录的数组 files = readdirSync(entry); for (let file of files) { const curPath = join(entry, file); // fs.statSync同步读取文件夹文件,如果是文件夹,在重复触发函数 if (statSync(curPath).isDirectory()) { // recurse deleteFolderRecursive(curPath); // 是文件delete file } else { unlinkSync(curPath); } } // 清除文件夹 rmdirSync(entry); } else { // console.log("文件夹不存在"); } }; export function writeFile(path: string | PathLike, data: any) { try { writeFileSync(path, data) } catch (err) { Error(error(err)) Error(error('文件写入失败')) } } export function readFile( path: string | PathLike, options?: { encoding?: null | undefined; flag?: string | undefined } | null ) { try { const data = readFileSync(path, options); return data; } catch (err) { Error(error(err)); Error(error('文件读取失败')); } } /** * @name 拷贝文件夹 * @export * @param {PathLike} currentDir * @param {PathLike} targetDir * @param {boolean} [overwrite=false] 是否覆盖已存在的文件 */ export function copyFolder(currentDir: PathLike, targetDir: PathLike, overwrite: boolean = false) { function handleFolder(currentDir: PathLike, targetDir: PathLike) { const files = readdirSync(currentDir, { withFileTypes: true }); for (let file of files) { const copyCurrentFileInfo = join(currentDir.toString(), file.name); const copyTargetFileInfo = join(targetDir.toString(), file.name); const readCurrentFile = existsSync(copyCurrentFileInfo); const readTargetFile = existsSync(copyTargetFileInfo); if (!readCurrentFile) { console.error(`操作失败,待拷贝的源路径${copyCurrentFileInfo}不存在`); throw new global.Error(`操作失败,待拷贝的源路径${copyCurrentFileInfo}不存在`); } else if (file.isFile() && readTargetFile && !overwrite) { // console.warn(`目标文件${copyTargetFileInfo}已存在,跳过复制`); continue; } else { if (file.isFile()) { // 使用同步复制确保文件完全写入 copyFileSync(copyCurrentFileInfo, copyTargetFileInfo); // console.log(`复制文件: ${copyCurrentFileInfo} -> ${copyTargetFileInfo}`); } else { try { accessSync(join(copyTargetFileInfo, '..'), constants.W_OK); if (!existsSync(copyTargetFileInfo)) { mkdirSync(copyTargetFileInfo); } // console.log(`创建文件夹: ${copyTargetFileInfo}`); copyFolder(copyCurrentFileInfo, copyTargetFileInfo, overwrite); } catch (error) { console.error('权限不足', error); throw error; } } } } } if (existsSync(currentDir)) { if (!existsSync(targetDir)) { mkdirSync(targetDir); // console.log(`创建目标文件夹: ${targetDir}`); } handleFolder(currentDir, targetDir); } else { console.error(`需要copy的文件夹不存在: ${currentDir}`); throw new global.Error(`需要copy的文件夹不存在: ${currentDir}`); } } /** * @name 检测文件/文件夹是否存在 * @export * @param {(PathLike | string)} path * @returns */ export function checkFileExists(path: PathLike | string) { return existsSync(path) } /** * @name 检测文件/文件夹是否存在,不存在则创建 * @export * @param {(PathLike | string)} path * @param {*} [data] * @param {checkFileExistsAndCreateType} [type=checkFileExistsAndCreateType.DIRECTORY] */ export function checkFileExistsAndCreate(path: PathLike | string, data?: any, type: checkFileExistsAndCreateType = checkFileExistsAndCreateType.DIRECTORY, overwrite?: boolean): void { if (!checkFileExists(path) || overwrite) { switch (type) { case checkFileExistsAndCreateType.DIRECTORY: mkdirSync(path) break; case checkFileExistsAndCreateType.FILE: writeFile(path, data) break; default: mkdirSync(path) break; } } else { throw new global.Error(`${path} already exists!`); } }