🌟 feat: 增加文件处理功能和错误处理

在 utils/file.js 中添加了 MIME 类型常量、通用错误处理函数以及对文件操作函数的改进。
- 添加了常量对象用于文件类型和 MIME 类型的映射
- 增加了错误处理函数 handleError 用于统一错误处理
- 修改了 checkAndRemoveFile、mkdirIfNotExists、deleteFolderRecursive 等函数,使用 handleError 处理异常
- 优化了 readCurrentDir 函数的参数和返回值类型注释
- 增加了 copyFiles 函数的参数类型注释和返回值类型
- 增加了 toBase64 函数的参数类型注释和返回值类型
- 修改了 getMimeType 函数,使用 path.extname 获取文件扩展名
- 增加了 getMediaFilesAndOthers 函数,用于区分图片、视频和其他
This commit is contained in:
zhiyu1998 2024-09-11 10:38:39 +08:00
parent 52371b339f
commit b467873397

View File

@ -1,9 +1,26 @@
import fs from "node:fs"; import fs from "node:fs";
import path from "path"; import path from "path";
// 常量提取
const mimeTypes = {
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.png': 'image/png',
'.gif': 'image/gif',
'.pdf': 'application/pdf',
'.txt': 'text/plain',
// 添加其他文件类型和MIME类型的映射
};
// 通用错误处理函数
function handleError(err) {
logger.error(err);
throw err;
}
/** /**
* 检查文件是否存在并且删除 * 检查文件是否存在并且删除
* @param file * @param {string} file - 文件路径
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
export async function checkAndRemoveFile(file) { export async function checkAndRemoveFile(file) {
@ -12,14 +29,14 @@ export async function checkAndRemoveFile(file) {
await fs.promises.unlink(file); await fs.promises.unlink(file);
} catch (err) { } catch (err) {
if (err.code !== 'ENOENT') { if (err.code !== 'ENOENT') {
throw err; handleError(err);
} }
} }
} }
/** /**
* 创建文件夹如果不存在 * 创建文件夹如果不存在
* @param dir * @param {string} dir - 文件夹路径
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
export async function mkdirIfNotExists(dir) { export async function mkdirIfNotExists(dir) {
@ -29,15 +46,15 @@ export async function mkdirIfNotExists(dir) {
if (err.code === 'ENOENT') { if (err.code === 'ENOENT') {
await fs.promises.mkdir(dir, { recursive: true }); await fs.promises.mkdir(dir, { recursive: true });
} else { } else {
throw err; handleError(err);
} }
} }
} }
/** /**
* 删除文件夹下所有文件 * 删除文件夹下所有文件
* @param {string} folderPath - 文件夹路径
* @returns {Promise<number>} * @returns {Promise<number>}
* @param folderPath
*/ */
export async function deleteFolderRecursive(folderPath) { export async function deleteFolderRecursive(folderPath) {
try { try {
@ -58,37 +75,34 @@ export async function deleteFolderRecursive(folderPath) {
await Promise.allSettled(actions); await Promise.allSettled(actions);
return files.length; return files.length;
} catch (error) { } catch (error) {
logger.error(error); handleError(error);
return 0; return 0;
} }
} }
/** /**
* 读取当前文件夹的所有文件和文件夹 * 读取当前文件夹的所有文件和文件夹
* @param path 路径 * @param {string} dirPath - 路径
* @param printTree 是否打印树状图 * @returns {Promise<string[]>} 返回一个包含文件名的数组
* @returns {Promise<*>} 返回一个包含文件名的数组
*/ */
export async function readCurrentDir(path) { export async function readCurrentDir(dirPath) {
try { try {
const files = await fs.promises.readdir(path); return await fs.promises.readdir(dirPath);
return files;
} catch (err) { } catch (err) {
logger.error(err); handleError(err);
} }
} }
/** /**
* 拷贝文件 * 拷贝文件
* @param srcDir 源文件目录 * @param {string} srcDir - 源文件目录
* @param destDir 目标文件目录 * @param {string} destDir - 目标文件目录
* @param specificFiles 过滤文件不填写就拷贝全部 * @param {string[]} [specificFiles=[]] - 过滤文件不填写就拷贝全部
* @returns {Promise<*|null>} * @returns {Promise<string[]>} 拷贝的文件列表
*/ */
export async function copyFiles(srcDir, destDir, specificFiles = []) { export async function copyFiles(srcDir, destDir, specificFiles = []) {
try { try {
await mkdirIfNotExists(destDir); await mkdirIfNotExists(destDir);
const files = await readCurrentDir(srcDir); const files = await readCurrentDir(srcDir);
// 如果 specificFiles 数组为空,拷贝全部文件;否则只拷贝指定文件 // 如果 specificFiles 数组为空,拷贝全部文件;否则只拷贝指定文件
@ -112,46 +126,34 @@ export async function copyFiles(srcDir, destDir, specificFiles = []) {
return copiedFiles return copiedFiles
} catch (error) { } catch (error) {
logger.error(error); handleError(error);
return []; return [];
} }
} }
/** /**
* 转换路径图片为base64格式 * 转换路径图片为base64格式
* @param filePath 图片路径 * @param {string} filePath - 图片路径
* @return {Promise<string>} * @returns {Promise<string>} Base64字符串
*/ */
export async function toBase64(filePath) { export async function toBase64(filePath) {
try { try {
// 读取文件数据 const fileData = await fs.promises.readFile(filePath);
const fileData = await fs.readFileSync(filePath);
// 将文件数据转换为Base64字符串
const base64Data = fileData.toString('base64'); const base64Data = fileData.toString('base64');
// 返回Base64字符串 // 返回Base64字符串
return `data:${getMimeType(filePath)};base64,${base64Data}`; return `data:${getMimeType(filePath)};base64,${base64Data}`;
} catch (error) { } catch (error) {
throw new Error(`读取文件时出错: ${error.message}`); handleError(error);
} }
} }
/** /**
* 辅助函数根据文件扩展名获取MIME类型 * 辅助函数根据文件扩展名获取MIME类型
* @param filePath * @param {string} filePath - 文件路径
* @return {*|string} * @returns {string} MIME类型
*/ */
function getMimeType(filePath) { function getMimeType(filePath) {
const mimeTypes = { const ext = path.extname(filePath).toLowerCase();
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.png': 'image/png',
'.gif': 'image/gif',
'.pdf': 'application/pdf',
'.txt': 'text/plain',
// 添加其他文件类型和MIME类型的映射
};
const ext = filePath.substring(filePath.lastIndexOf('.')).toLowerCase();
return mimeTypes[ext] || 'application/octet-stream'; return mimeTypes[ext] || 'application/octet-stream';
} }
@ -161,8 +163,8 @@ function getMimeType(filePath) {
* @returns {Promise<Object>} 包含图片和视频文件名的对象 * @returns {Promise<Object>} 包含图片和视频文件名的对象
*/ */
export async function getMediaFilesAndOthers(folderPath) { export async function getMediaFilesAndOthers(folderPath) {
return new Promise((resolve, reject) => { try {
// 定义图片和视频的扩展名 const files = await fs.promises.readdir(folderPath);
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']; const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'];
const videoExtensions = ['.mp4', '.mkv', '.avi', '.mov', '.wmv', '.flv', '.webm']; const videoExtensions = ['.mp4', '.mkv', '.avi', '.mov', '.wmv', '.flv', '.webm'];
@ -171,26 +173,19 @@ export async function getMediaFilesAndOthers(folderPath) {
const videos = []; const videos = [];
const others = []; const others = [];
// 读取文件夹中的所有文件 files.forEach(file => {
fs.readdir(folderPath, (err, files) => { const ext = path.extname(file).toLowerCase();
if (err) { if (imageExtensions.includes(ext)) {
return reject('无法读取文件夹: ' + err); images.push(file);
} else if (videoExtensions.includes(ext)) {
videos.push(file);
} else {
others.push(file);
} }
files.forEach(file => {
const ext = path.extname(file).toLowerCase();
if (imageExtensions.includes(ext)) {
images.push(file);
} else if (videoExtensions.includes(ext)) {
videos.push(file);
} else {
others.push(file);
}
});
// 返回包含图片和视频的对象
resolve({ images, videos, others });
}); });
});
return { images, videos, others };
} catch (err) {
handleError(err);
}
} }