2023-03-07 20:57:05 +08:00

196 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import config from '../config';
import * as path from 'path';
import * as fs from 'fs-extra';
import ProcessHelper from '../util/ProcesHelper';
import FileObj from '../entity/vo/FileObj';
import SavePathDao from '../dao/SavePathDao';
import SavePath from '../entity/po/SavePath';
import ErrorHelper from "../util/ErrorHelper";
let numberSet = new Set(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
class FileService {
static async readPath(pathStr: string, showHidden: boolean): Promise<Array<FileObj>> {
pathStr = decodeURIComponent(pathStr);
let fileList = [];
if (pathStr.trim().length == 0) {
//获取根目录路径
if (config.isWindows) {
//windows下
let std: string = (await ProcessHelper.exec('wmic logicaldisk get caption')).replace('Caption', '');
fileList = std
.split('\r\n')
.filter((item) => item.trim().length > 0)
.map((item) => item.trim());
} else {
//linux下
pathStr = '/';
fileList = await fs.readdir(pathStr);
}
} else {
if (!(fs.pathExists(pathStr))) {
throw new Error("路径不存在");
}
fileList = await fs.readdir(pathStr);
}
let folderList: Array<FileObj> = [];
let files: Array<FileObj> = [];
for (let index in fileList) {
try {
let stat = await fs.stat(path.join(pathStr, fileList[index]));
if (fileList[index].startsWith('.')) {
if (showHidden) {
(stat.isDirectory() ? folderList : files).push(
new FileObj(fileList[index], pathStr, stat.isDirectory(), stat.size, stat.birthtime.getTime(), stat.mtime.getTime()),
);
}
} else {
(stat.isDirectory() ? folderList : files).push(
new FileObj(fileList[index], pathStr, stat.isDirectory(), stat.size, stat.birthtime.getTime(), stat.mtime.getTime()),
);
}
} catch (e) {
console.error(e);
}
}
folderList.sort((a, b) => FileService.compareStr(a.name, b.name)).push(...files.sort((a, b) => FileService.compareStr(a.name, b.name)));
return folderList;
}
/**
* 递归读取文件夹下所有的文件
*/
static async readRecursion(folders: Array<FileObj>): Promise<Array<FileObj>> {
let res = [];
await this.readDirRecursion(res, folders, 1);
return res;
}
private static async readDirRecursion(res: Array<FileObj>, folders: Array<FileObj>, depth: number): Promise<void> {
if (depth > 10) {
throw ErrorHelper.Error400("递归读取超过10层,强制结束");
}
if (folders == null || folders.length == 0) {
return;
}
for (let i in folders) {
let file = folders[i];
if (!file.isFolder) {
res.push(file);
} else {
let filePath = path.join(file.path, file.name);
let temp = (await fs.readdir(filePath)).map(item => {
let stat = fs.statSync(path.join(filePath, item));
return new FileObj(item, filePath, stat.isDirectory(), stat.size, stat.birthtime.getTime(), stat.mtime.getTime());
});
await FileService.readDirRecursion(res, temp, depth + 1);
}
}
}
static async checkExist(pathStr: string) {
return await fs.pathExists(pathStr);
}
/**
* 收藏路径
* @param saveObj
* @returns
*/
static async savePath(saveObj: SavePath) {
await SavePathDao.addOne(saveObj);
return saveObj;
}
/**
* 获取保存列表
* @returns
*/
static async getSaveList() {
return await SavePathDao.getAll();
}
/**
* 删除
* @param id
* @returns
*/
static async deleteOne(id) {
return await SavePathDao.delete(id);
}
/**
* 数字字母混合排序
* @param a str
* @param b str
*/
static compareStr(a: string, b: string) {
let an = a.length;
let bn = b.length;
for (let i = 0; i < an;) {
let charA = FileService.readChar(a, i, an);
let charB = FileService.readChar(b, i, bn);
if (charB.length == 0) {
return 1;
}
if (charA !== charB) {
//读取字符串不相等说明可以得到排序结果
//如果都为数字,按照数字的比较方法,否则按照字符串比较
return numberSet.has(charA.charAt(0)) && numberSet.has(charB.charAt(0)) ? Number(charA) - Number(charB) : charA.localeCompare(charB);
}
i += charA.length;
}
//排到最后都没分结果说明相等
return 0;
}
/**
* 读取字符,如果字符为数字就读取整个数字
* @param a a
* @param n 数字长度
*/
static readChar(a: string, i: number, n: number) {
let res = "";
for (; i < n; i++) {
let char = a.charAt(i);
if (numberSet.has(char)) {
//如果当前字符是数字,添加到结果中
res += char;
} else {
//如果不为数字但是为第一个字符直接返回否则返回res
if (res.length == 0) {
return char;
} else {
return res;
}
}
}
return res;
}
/**
* delete batch
* @param files files
*/
static async deleteBatch(files: Array<FileObj>): Promise<void> {
if (files == null || files.length == 0) {
return;
}
for (let i in files) {
await fs.remove(path.join(files[i].path, files[i].name));
}
}
/**
* rename file from source to target
* @param source sourceFile
* @param target targetFile
*/
static async rename(source: FileObj, target: FileObj): Promise<void> {
await fs.rename(path.join(source.path, source.name), path.join(target.path, target.name));
}
}
export default FileService;