实战项目7:文件管理器¶
项目概述¶
使用 Python 实现一个命令行文件管理器,支持目录浏览、文件操作(复制、移动、删除、重命名)、内容搜索和批量处理等功能。这个项目能帮助你深入理解 Python 的文件与目录操作,是巩固标准库使用的绝佳练习。
学习目标¶
- 熟练使用
os、shutil、pathlib等标准库模块 - 掌握递归遍历目录树的写法
- 学习命令行交互程序的设计思路
- 理解异常处理在文件操作中的重要性
- 了解批量文件处理的实用技巧
功能需求¶
核心功能¶
- 列出当前目录内容(含文件大小、修改时间)
- 切换目录、查看当前路径
- 复制、移动、删除文件和目录
- 创建目录、重命名文件
- 按名称/扩展名搜索文件
- 批量重命名(如统一替换扩展名)
项目结构¶
代码实现¶
完整代码(file_manager.py):
import os
import shutil
import time
from pathlib import Path
def fmt_size(size):
"""把字节数格式化为人类可读的形式。"""
for unit in ("B", "KB", "MB", "GB"):
if size < 1024:
return f"{size:.1f} {unit}"
size /= 1024
return f"{size:.1f} TB"
def list_dir(path):
"""列出目录内容。"""
entries = sorted(Path(path).iterdir(),
key=lambda p: (p.is_file(), p.name.lower()))
if not entries:
print("(空目录)")
return
for entry in entries:
if entry.is_dir():
print(f" <DIR> {entry.name}/")
else:
stat = entry.stat()
mtime = time.strftime("%Y-%m-%d %H:%M",
time.localtime(stat.st_mtime))
print(f"{fmt_size(stat.st_mtime and stat.st_size):>10} "
f"{mtime} {entry.name}")
def safe_do(func, *args, **kwargs):
"""统一处理文件操作中的异常。"""
try:
func(*args, **kwargs)
print("操作成功")
except FileNotFoundError:
print("错误:路径不存在")
except PermissionError:
print("错误:权限不足")
except OSError as e:
print(f"错误:{e}")
def search(root, keyword):
"""递归搜索文件名包含 keyword 的文件。"""
count = 0
for dirpath, dirnames, filenames in os.walk(root):
for name in filenames:
if keyword.lower() in name.lower():
print(os.path.join(dirpath, name))
count += 1
if count >= 50:
print("(结果过多,仅显示前 50 条)")
return
print(f"共找到 {count} 个文件")
def batch_rename(folder, old_ext, new_ext):
"""把 folder 下所有 old_ext 文件重命名为 new_ext。"""
renamed = 0
for p in Path(folder).glob(f"*{old_ext}"):
new_name = p.with_suffix(new_ext)
if not new_name.exists():
p.rename(new_name)
renamed += 1
print(f"共重命名 {renamed} 个文件")
HELP = """
命令列表:
ls 列出当前目录
cd <目录> 切换目录(.. 返回上级)
pwd 显示当前路径
mkdir <名称> 创建目录
rm <路径> 删除文件或目录
cp <源> <目标> 复制文件或目录
mv <源> <目标> 移动/重命名
find <关键词> 搜索文件
rename <旧后缀> <新后缀> 批量重命名
help 显示帮助
exit 退出
"""
def main():
cwd = os.getcwd()
print("Python 文件管理器(输入 help 查看命令)")
while True:
cmd = input(f"\n{cwd}> ").strip()
if not cmd:
continue
parts = cmd.split()
action, args = parts[0], parts[1:]
if action == "exit":
print("再见!")
break
elif action == "help":
print(HELP)
elif action == "ls":
list_dir(cwd)
elif action == "pwd":
print(cwd)
elif action == "cd" and args:
target = os.path.abspath(os.path.join(cwd, args[0]))
if os.path.isdir(target):
cwd = target
else:
print("错误:目录不存在")
elif action == "mkdir" and args:
safe_do(os.makedirs, os.path.join(cwd, args[0]), exist_ok=True)
print("目录已创建")
elif action == "rm" and args:
target = os.path.join(cwd, args[0])
if os.path.isdir(target):
confirm = input(f"确认删除目录 {target} 及其全部内容?(y/N) ")
if confirm.lower() == "y":
safe_do(shutil.rmtree, target)
else:
safe_do(os.remove, target)
elif action == "cp" and len(args) == 2:
src, dst = os.path.join(cwd, args[0]), os.path.join(cwd, args[1])
if os.path.isdir(src):
safe_do(shutil.copytree, src, dst)
else:
safe_do(shutil.copy2, src, dst)
elif action == "mv" and len(args) == 2:
safe_do(shutil.move,
os.path.join(cwd, args[0]), os.path.join(cwd, args[1]))
elif action == "find" and args:
search(cwd, args[0])
elif action == "rename" and len(args) == 2:
batch_rename(cwd, args[0], args[1])
else:
print("未知命令,输入 help 查看帮助")
if __name__ == "__main__":
main()
运行指南¶
示例会话:
C:\Users\demo\Documents> ls
<DIR> 项目/
1.2 KB 2024-05-01 10:30 笔记.txt
C:\Users\demo\Documents> find 笔记
C:\Users\demo\Documents\笔记.txt
共找到 1 个文件
扩展功能建议¶
基础扩展¶
- 显示隐藏文件开关
- 按大小/时间排序选项
cat <文件>查看文本文件内容
进阶扩展¶
- 使用
argparse改造为一次性命令行工具 - 回收站机制:删除的文件先移动到
.trash目录 - 操作日志记录(写入
history.log)
高级扩展¶
- 基于
tkinter或PyQt开发图形界面版本 - 集成
watchdog库实现目录变化监控 - 支持压缩包的创建与解压(
zipfile、tarfile)
常见问题¶
Q: 删除目录时为什么需要二次确认?¶
A: shutil.rmtree 会不可逆地删除整个目录树,二次确认可以防止误操作。实际产品中建议配合回收站机制使用。
Q: Windows 和 Linux 路径有什么区别?¶
A: 建议始终使用 os.path.join 或 pathlib.Path 拼接路径,它们会自动处理不同操作系统的路径分隔符。
Q: 如何处理文件名乱码?¶
A: Windows 下部分文件名编码可能异常,可以用 os.fsdecode 做容错解码。
项目总结¶
本项目实现了一个功能完整的命令行文件管理器,涵盖了:
- 文件系统操作:
os、shutil、pathlib的综合运用 - 递归遍历:目录树的搜索与处理
- 交互设计:REPL 式命令行循环
- 异常处理:统一的安全执行封装
- 用户体验:确认机制、格式化输出、帮助信息
下一步¶
- 给项目加上单元测试(
pytest+tmp_path) - 实现图形界面版本
- 挑战实战项目8:聊天室程序,学习网络编程
祝你开发愉快!