""" 文件管理器模块 提供文件的读写、列表、删除等操作 """ import os import json import shutil from typing import List, Dict, Any from pathlib import Path class FileManager: """ 文件管理器类 负责处理所有文件相关的操作,包括读写、列表、删除等 """ def __init__(self, base_path: str = None): """ 初始化文件管理器 Args: base_path (str): 基础路径,默认为当前工作目录 """ self.base_path = Path(base_path) if base_path else Path.cwd() self.workspace_path = self.base_path / 'workspace' # 确保工作目录存在 self.workspace_path.mkdir(exist_ok=True) def list_files(self, path: str = '', include_hidden: bool = False) -> List[Dict[str, Any]]: """ 列出指定路径下的文件和目录 Args: path (str): 相对路径,相对于工作目录 include_hidden (bool): 是否包含隐藏文件 Returns: List[Dict[str, Any]]: 文件和目录信息列表 """ target_path = self.workspace_path / path if not target_path.exists(): raise FileNotFoundError(f"Path does not exist: {path}") if not target_path.is_dir(): raise NotADirectoryError(f"Path is not a directory: {path}") items = [] for item in sorted(target_path.iterdir()): if not include_hidden and item.name.startswith('.'): continue stat = item.stat() items.append({ 'name': item.name, 'path': str(item.relative_to(self.workspace_path)), 'type': 'directory' if item.is_dir() else 'file', 'size': stat.st_size if item.is_file() else 0, 'modified': stat.st_mtime, 'extension': item.suffix.lower() if item.is_file() else '', 'is_markdown': item.suffix.lower() == '.md' }) return items def read_file(self, path: str) -> str: """ 读取文件内容 Args: path (str): 文件路径,相对于工作目录 Returns: str: 文件内容 """ file_path = self.workspace_path / path if not file_path.exists(): raise FileNotFoundError(f"File not found: {path}") if not file_path.is_file(): raise IsADirectoryError(f"Path is a directory: {path}") try: with open(file_path, 'r', encoding='utf-8') as f: return f.read() except UnicodeDecodeError: # 尝试其他编码 with open(file_path, 'r', encoding='gbk') as f: return f.read() def write_file(self, path: str, content: str, create_dirs: bool = True) -> None: """ 写入文件内容 Args: path (str): 文件路径,相对于工作目录 content (str): 文件内容 create_dirs (bool): 是否自动创建目录 """ file_path = self.workspace_path / path if create_dirs: file_path.parent.mkdir(parents=True, exist_ok=True) with open(file_path, 'w', encoding='utf-8') as f: f.write(content) def delete_file(self, path: str) -> None: """ 删除文件或目录 Args: path (str): 文件或目录路径,相对于工作目录 """ target_path = self.workspace_path / path if not target_path.exists(): raise FileNotFoundError(f"Path does not exist: {path}") if target_path.is_dir(): shutil.rmtree(target_path) else: target_path.unlink() def create_directory(self, path: str) -> None: """ 创建目录 Args: path (str): 目录路径,相对于工作目录 """ dir_path = self.workspace_path / path dir_path.mkdir(parents=True, exist_ok=True) def file_exists(self, path: str) -> bool: """ 检查文件是否存在 Args: path (str): 文件路径,相对于工作目录 Returns: bool: 文件是否存在 """ return (self.workspace_path / path).exists() def get_file_info(self, path: str) -> Dict[str, Any]: """ 获取文件详细信息 Args: path (str): 文件路径,相对于工作目录 Returns: Dict[str, Any]: 文件详细信息 """ file_path = self.workspace_path / path if not file_path.exists(): raise FileNotFoundError(f"File not found: {path}") stat = file_path.stat() return { 'name': file_path.name, 'path': str(file_path.relative_to(self.workspace_path)), 'type': 'directory' if file_path.is_dir() else 'file', 'size': stat.st_size, 'modified': stat.st_mtime, 'created': stat.st_ctime, 'extension': file_path.suffix.lower(), 'is_markdown': file_path.suffix.lower() == '.md' } def search_files(self, pattern: str, path: str = '') -> List[str]: """ 搜索文件 Args: pattern (str): 搜索模式(支持通配符) path (str): 搜索起始路径,相对于工作目录 Returns: List[str]: 匹配的文件路径列表 """ target_path = self.workspace_path / path if not target_path.exists(): return [] matches = [] for file_path in target_path.rglob(pattern): if file_path.is_file(): matches.append(str(file_path.relative_to(self.workspace_path))) return matches def copy_file(self, src_path: str, dest_path: str) -> None: """ 复制文件 Args: src_path (str): 源文件路径 dest_path (str): 目标文件路径 """ src = self.workspace_path / src_path dest = self.workspace_path / dest_path if not src.exists(): raise FileNotFoundError(f"Source file not found: {src_path}") dest.parent.mkdir(parents=True, exist_ok=True) shutil.copy2(src, dest) def move_file(self, src_path: str, dest_path: str) -> None: """ 移动文件 Args: src_path (str): 源文件路径 dest_path (str): 目标文件路径 """ src = self.workspace_path / src_path dest = self.workspace_path / dest_path if not src.exists(): raise FileNotFoundError(f"Source file not found: {src_path}") dest.parent.mkdir(parents=True, exist_ok=True) shutil.move(str(src), str(dest))