// ============================================================ // canvas/walk.ts — 目录遍历算法 // // 职责: // - 递归遍历目录,收集所有匹配扩展名的文件 // - 跳过隐藏文件和文件夹 // ============================================================ import fs from 'node:fs'; import path from 'node:path'; import type { ScanEntry } from './types'; /** * 递归遍历目录,收集所有匹配扩展名的文件。 * * @param root - 根目录路径 * @param extensions - 允许的文件扩展名列表(不含点号) * @param recursive - 是否递归遍历子目录 * @returns 文件列表 */ export function walkDirectory( root: string, extensions: string[], recursive: boolean, ): ScanEntry[] { const results: ScanEntry[] = []; const extSet = new Set(extensions.map((e) => e.toLowerCase())); function walk(dir: string) { let entries: fs.Dirent[]; try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; // 权限不足等,跳过该目录 } for (const entry of entries) { // 跳过隐藏文件和文件夹 if (entry.name.startsWith('.')) continue; const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { if (recursive) walk(fullPath); } else if (entry.isFile()) { const ext = path.extname(entry.name).slice(1).toLowerCase(); if (extSet.has(ext)) { try { const stat = fs.statSync(fullPath); results.push({ path: fullPath, fileName: entry.name, ext, fileSize: stat.size, modifiedAt: stat.mtime.toISOString(), }); } catch { // 文件不可访问,跳过 } } } } } walk(root); return results; }