使用Python Watchdog库实现文件系统监控
Watchdog是一个优秀的Python库,用于监控文件系统事件。它可以检测文件或目录的创建、修改、删除和移动等操作,并触发相应的回调函数。本文将介绍Watchdog的基本用法,并通过一个实际案例展示如何用它来监控下载目录并自动转换ICO文件为PNG格式。
Watchdog简介
Watchdog库的主要组件包括:
- Observer - 监控文件系统变化的核心类
- FileSystemEventHandler - 处理文件系统事件的基类
- 各种事件类 - 如FileCreatedEvent, FileModifiedEvent等
安装Watchdog
pip install watchdog
实际案例:自动转换ICO文件为PNG
下面是一个完整的示例,它监控用户的下载目录,当检测到新的ICO文件时,自动将其转换为PNG格式(使用ImageMagick的convert工具)。
import os
import time
import subprocess
import shutil
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class ICOHandler(FileSystemEventHandler):
def __init__(self, download_dir, convert_exe):
self.download_dir = download_dir
self.processed_files = set()
self.convert_exe = convert_exe
# 初始化时处理已存在的ico文件
for filename in os.listdir(download_dir):
if filename.lower().endswith('.ico'):
self.processed_files.add(filename)
self.convert_ico_to_png(filename)
def on_created(self, event):
if not event.is_directory and event.src_path.lower().endswith('.ico'):
filename = os.path.basename(event.src_path)
if filename not in self.processed_files:
self.processed_files.add(filename)
print(f"检测到新的ICO文件: {filename}")
self.convert_ico_to_png(filename)
def convert_ico_to_png(self, ico_filename):
ico_path = os.path.join(self.download_dir, ico_filename)
base_name = os.path.splitext(ico_filename)[0]
# 临时输出目录
temp_dir = os.path.join(self.download_dir, f"{base_name}_temp")
os.makedirs(temp_dir, exist_ok=True)
# 临时输出路径模板
temp_output = os.path.join(temp_dir, f"{base_name}_%d.png")
try:
# 使用ImageMagick的convert命令转换ICO到PNG
cmd = [
self.convert_exe,
ico_path,
temp_output
]
subprocess.run(cmd, check=True)
print(f"已转换: {ico_filename} -> 多个PNG文件")
# 找出最大的PNG文件
largest_file = self.find_largest_png(temp_dir)
if largest_file:
final_output = os.path.join(self.download_dir, f"{base_name}.png")
os.rename(largest_file, final_output)
print(f"已保存最大的PNG文件: {final_output}")
# 清理临时目录
self.cleanup_temp_dir(temp_dir)
except subprocess.CalledProcessError as e:
print(f"转换失败: {e}")
self.cleanup_temp_dir(temp_dir)
except Exception as e:
print(f"发生错误: {e}")
self.cleanup_temp_dir(temp_dir)
def find_largest_png(self, directory):
largest_size = 0
largest_file = None
for filename in os.listdir(directory):
if filename.lower().endswith('.png'):
filepath = os.path.join(directory, filename)
file_size = os.path.getsize(filepath)
if file_size > largest_size:
largest_size = file_size
largest_file = filepath
return largest_file
def cleanup_temp_dir(self, temp_dir):
try:
for filename in os.listdir(temp_dir):
filepath = os.path.join(temp_dir, filename)
os.remove(filepath)
os.rmdir(temp_dir)
except Exception as e:
print(f"清理临时目录时出错: {e}")
def main():
# 获取用户下载目录
download_dir = os.path.expanduser('~/Downloads')
# 在这里设置ImageMagick的convert.exe的完整路径
# 如果'convert'在您的系统PATH中,您可以直接写'convert'
# 否则,请提供完整路径,例如: r'C:\Program Files\ImageMagick-7.1.1-Q16-HDRI\convert.exe'
convert_exe = 'convert'
# 查找并打印convert命令的完整路径
# 如果用户没有提供绝对路径,则在PATH中搜索
if convert_exe == 'convert' and not os.path.isabs(convert_exe):
full_path = shutil.which(convert_exe)
if full_path:
print(f"查找到 'convert' 的完整路径是: {full_path}")
convert_exe = full_path # 使用完整路径以提高可靠性
else:
print(f"警告: 在系统PATH中找不到 '{convert_exe}'。程序可能会失败。")
# 确保ImageMagick已安装
try:
subprocess.run([convert_exe, '--version'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except (subprocess.CalledProcessError, FileNotFoundError):
print(f"错误: 无法执行 '{convert_exe}'。")
print("请检查路径是否正确,或ImageMagick是否已安装并添加到系统PATH中。")
print("您可以修改脚本中 'convert_exe' 变量的值为 convert.exe 的完整路径。")
print("ImageMagick下载地址: https://imagemagick.org/script/download.php")
return
print(f"开始监控目录: {download_dir}")
print("按Ctrl+C停止监控")
event_handler = ICOHandler(download_dir, convert_exe)
observer = Observer()
observer.schedule(event_handler, download_dir, recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
if __name__ == "__main__":
main()
代码解析
ICOHandler类 - 继承自FileSystemEventHandler,处理文件系统事件
on_created
: 当新文件创建时触发convert_ico_to_png
: 转换ICO文件为PNG格式find_largest_png
: 找出最大的PNG文件(ICO可能包含多个尺寸)cleanup_temp_dir
: 清理临时目录
Observer设置 - 创建观察者并设置监控目录
ImageMagick检查 - 确保转换工具可用
使用场景
这个脚本特别适合需要批量处理ICO图标的场景,例如:
- 网页开发者需要将ICO转换为PNG用于网站
- UI设计师需要提取ICO中的最大尺寸图标
- 系统管理员需要自动化处理下载的图标文件
扩展思路
Watchdog的强大之处在于它可以应用于各种文件系统监控场景,例如:
- 自动备份新创建的文件
- 监控日志文件变化并发送通知
- 自动解压下载的压缩文件
- 照片自动分类整理
总结
Watchdog是一个功能强大且易于使用的Python库,可以轻松实现文件系统监控功能。通过本文的案例,我们展示了如何用它来监控特定目录并自动处理新文件。你可以根据自己的需求修改这个示例,实现更复杂的文件处理逻辑。
要运行这个脚本,你需要先安装ImageMagick并将其添加到系统PATH中,或者修改脚本中的convert_exe
变量为ImageMagick convert工具的完整路径。