239 lines
7.2 KiB
TypeScript
Raw Normal View History

2024-07-13 15:44:13 +08:00
import fs from 'fs'
import { isEmpty } from 'lodash'
import path from 'path'
const fspromises = fs.promises
2024-06-06 13:12:04 +08:00
/**
*
* @param {*} path
* @returns true表示存在false表示不存在
*/
export async function CheckFileOrDirExist(path) {
2024-07-13 15:44:13 +08:00
try {
await fspromises.access(path)
return true // 文件或目录存在
} catch (error) {
return false // 文件或目录不存在
}
2024-06-06 13:12:04 +08:00
}
2024-06-24 13:11:19 +08:00
// 检查文件夹是不是存在,不存在的话,创建
export async function CheckFolderExistsOrCreate(folderPath) {
2024-07-13 15:44:13 +08:00
try {
if (!(await CheckFileOrDirExist(folderPath))) {
await fspromises.mkdir(folderPath, { recursive: true })
2024-06-24 13:11:19 +08:00
}
2024-07-13 15:44:13 +08:00
} catch (error) {
throw new Error(error)
}
2024-06-24 13:11:19 +08:00
}
2024-07-13 15:44:13 +08:00
2024-06-24 13:11:19 +08:00
/**
*
* @param {*} rootPath
* @param {*} subPath
2024-07-13 15:44:13 +08:00
* @returns
2024-06-24 13:11:19 +08:00
*/
2024-08-03 12:46:12 +08:00
export function JoinPath(rootPath: string, subPath: string): string {
2024-07-13 15:44:13 +08:00
// 判断第二个地址是不是存在不存在返回null存在返回拼接后的地址
if (subPath && !isEmpty(subPath)) {
return path.resolve(rootPath, subPath)
} else {
return null
}
2024-06-24 13:11:19 +08:00
}
2024-07-13 15:44:13 +08:00
/**
*
* @param {*} folderPath
2024-08-03 12:46:12 +08:00
* @param {*} isDeleteOut false
2024-07-13 15:44:13 +08:00
*/
2024-08-03 12:46:12 +08:00
export async function DeleteFolderAllFile(folderPath: string, isDeleteOut: boolean = false): Promise<void> {
2024-07-13 15:44:13 +08:00
try {
let folderIsExist = await CheckFileOrDirExist(folderPath)
if (!folderIsExist) {
throw new Error('目的文件夹不存在,' + folderPath)
}
// 开始删除
let files = await fspromises.readdir(folderPath)
2024-08-03 12:46:12 +08:00
for (const file of files) {
const curPath = path.join(folderPath, file);
const stat = await fspromises.stat(curPath);
if (stat.isDirectory()) {
2024-07-13 15:44:13 +08:00
// 判断是不是文件夹
2024-08-03 12:46:12 +08:00
await DeleteFolderAllFile(curPath); // 递归删除文件夹内容
await fspromises.rmdir(curPath); // 删除空文件夹
2024-07-13 15:44:13 +08:00
} else {
// 删除文件
2024-08-03 12:46:12 +08:00
await fspromises.unlink(curPath);
2024-07-13 15:44:13 +08:00
}
2024-08-03 12:46:12 +08:00
}
// 判断是不是要删除最外部的文件夹
if (isDeleteOut) {
await fspromises.rmdir(folderPath)
}
2024-07-13 15:44:13 +08:00
} catch (error) {
throw error
}
}
2024-06-24 13:11:19 +08:00
/**
*
* @param {*} source
* @param {*} target
* @param {*} checkParent false
*/
export async function CopyFileOrFolder(source, target, checkParent = false) {
2024-07-13 15:44:13 +08:00
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 })
}
}
2024-06-24 13:11:19 +08:00
2024-07-13 15:44:13 +08:00
// 判断是不是文件夹
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)
2024-06-24 13:11:19 +08:00
} else {
2024-07-13 15:44:13 +08:00
await fspromises.copyFile(srcPath, tgtPath)
2024-06-24 13:11:19 +08:00
}
2024-07-13 15:44:13 +08:00
}
2024-06-24 13:11:19 +08:00
}
2024-07-13 15:44:13 +08:00
if (isDirectory) {
// 创建目标文件夹
await copyDirectory(source, target)
} else {
// 复制文件
await fspromises.copyFile(source, target)
}
} catch (error) {
throw error
}
}
2024-06-24 13:11:19 +08:00
2024-06-06 13:12:04 +08:00
/** *
* @param {*} path
* @returns true false
*/
export async function IsDirectory(path) {
2024-07-13 15:44:13 +08:00
try {
const stat = await fspromises.stat(path)
return stat.isDirectory()
} catch (error) {
throw new Error(`获取文件夹信息失败: ${path}`)
}
2024-06-06 13:12:04 +08:00
}
/**
*
* @param {*} source_path /
* @param {*} target_path /
*/
2024-08-03 12:46:12 +08:00
export async function BackupFileOrFolder(source_path: string, target_path: string): Promise<void> {
2024-07-13 15:44:13 +08:00
try {
// 判断父文件夹是否存在,不存在创建
const parent_path = path.dirname(target_path)
if (!(await CheckFileOrDirExist(parent_path))) {
await fspromises.mkdir(parent_path, { recursive: true })
}
2024-06-06 13:12:04 +08:00
2024-07-13 15:44:13 +08:00
// 判断是不是文件夹
const isDirectory = await IsDirectory(source_path)
2024-06-06 13:12:04 +08:00
2024-07-13 15:44:13 +08:00
if (isDirectory) {
// 复制文件夹
await fspromises.rename(source_path, target_path)
} else {
// 复制文件
2024-08-03 12:46:12 +08:00
await fspromises.copyFile(source_path, target_path)
2024-06-06 13:12:04 +08:00
}
2024-07-13 15:44:13 +08:00
} catch (error) {
throw new Error(error)
}
2024-06-06 13:12:04 +08:00
}
/**
*
* @param {*} folderPath
* @param {*} extensions
* @returns
*/
2024-08-03 12:46:12 +08:00
export async function GetFilesWithExtensions(folderPath: string, extensions: string[]): Promise<string[]> {
2024-07-13 15:44:13 +08:00
try {
// 判断当前是不是文件夹
if (!(await IsDirectory(folderPath))) {
throw new Error('输入的不是有效的文件夹地址')
2024-06-06 13:12:04 +08:00
}
2024-07-13 15:44:13 +08:00
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)
}
}
2024-08-03 12:46:12 +08:00
/**
*
* @param filePath
* @returns kb单位
*/
export async function GetFileSize(filePath: string): Promise<number> {
try {
if (!(await CheckFileOrDirExist(filePath))) {
throw new Error("获取文件大小,指定的文件不存在");
}
const stats = await fspromises.stat(filePath);
return stats.size / 1024
} catch (error) {
throw error
}
}