Python实现监听目录并取消文件只读属性
作者:Commas.KM
一、前言
通过新版微信接收的文件都被修改了权限,文件均被设置为“只读”。或许这对于微信来说是挺安全的,但是却给我们带来了不少的麻烦,想修改点东西,必须先取消文件只读属性,否者无法保存。
前段时间写过关于文件权限的文章(《python设置文件只读与取消文件只读》,结合目录遍历的知识(《python3遍历目录的三种方法浅谈》),再加个定时器不断遍历 微信接收文件的目录 ,确实可以解决问题,但不是本文所要讲解的,感兴趣的小伙伴可以自行尝试下。
虽然微信版本在持续更新,但是“文件被设为只读”的行为却没有更改,看来只能用程序打败程序,监听微信接收文件的目录,接收一个文件就处理一个文件的方式,去解决文件只读的问题。
二、第三方监听目录变化库
在 Python 的标准库中,没有直接用于监听文件目录变化的内置模块。有几个流行的第三方库可以用于监听文件目录的变化,如下:
(1)Watchdog库
Watchdog 是一个功能强大且易于使用的库,提供了监视文件和目录变化的功能。它支持各种事件,如文件创建、修改、删除等,并可以在这些事件发生时执行自定义的回调函数。Watchdog库在 Python 社区中广泛使用,并且有良好的文档和示例代码。
(2)Pyinotify库
Pyinotify 是一个与 Linux 内核中的 inotify 机制集成的库,可以高效地监视文件和目录的变化。它提供了 Pythonic 的 API,可以轻松地处理文件事件。Pyinotify 对于需要在Linux平台上进行文件监控的任务非常有用。
(3)Gamin库
Gamin 是另一个用于文件监控的库,它使用 Linux 上的 Gamin 守护进程作为后端。Gamin 库提供了一个简单的接口来监视文件和目录的变化,并可以触发相应的事件。
(4)PyFilesystem2库
PyFilesystem2 是一个通用的文件系统抽象库,它可以处理各种文件系统和存储。虽然它的主要目的是提供一个统一的 API 来访问不同类型的文件系统,但它也具有监视文件变化的功能。
三、监听目录取消文件只读
为了简化开发,这里打算采用第三方库 watchdog 来实现我们的需求。
(1)首先,安装watchdog库
pip install watchdog
如果不想污染全局库,想安装在虚拟环境中,可以这样做:
首先,创建一个虚拟环境 chmod_watchdog,virtualenv chmod_watchdog;
其次,激活z虚拟环境,\chmod_watchdog\Scripts\activate;
接着,安装 watchdog 库,pip install watchdog;
完成工作并想要退出虚拟环境,\chmod_watchdog\Scripts\deactivate
(2)取消文件只读属性
判断文件是否只读
def is_file_read_only(file_path): if os.access(file_path, os.W_OK): # 如果文件或目录具有指定的权限,返回True。 return False else: # 如果文件或目录不具有指定的权限, # 或者检查过程中发生错误,返回False。 return True
取消文件的只读属性
def unset_file_read_only(file_path): # 获取当前文件的权限标志位 file_stat = os.stat(file_path) # 取消只读属性,将其权限更改为可写 new_mode = file_stat.st_mode | stat.S_IWUSR # 设置新的权限标志位 os.chmod(file_path, new_mode)
(3)事件处理器对象
创建事件处理器对象
class MyEventHandler(FileSystemEventHandler): def on_any_event(self, event): if event.is_directory: # 忽略文件夹的变化 return if event.event_type == 'created' or event.event_type == 'modified': # 只处理新建和修改事件 file_path = event.src_path remove_read_only(file_path) event_handler = MyEventHandler()
取消文件只读属性,函数会在文件变化时被调用
def remove_read_only(file_path): # file_path 参数是变化的文件路径 print("文件已变化:", file_path) # 判断文件是否只读 if is_file_read_only(file_path): # 文件是只读的 # 取消文件的只读属性 unset_file_read_only(file_path) else: # 文件不是只读的 pass
(4)观察者对象
创建观察者对象
observer = Observer()
将自定义的事件处理器和要监视的目录绑定在一起
- event_handler:我们定义的自定义事件处理器的实例;
- directory:需要监视的目录路径;
- recursive=True 表示要递归地监视目录中的子目录。
observer.schedule(event_handler, directory, recursive=True)
启动观察器,开始监听目录的变化
observer.start()
保持文件监视器(Observer)持续运行,并在收到键盘中断信号(KeyboardInterrupt)时停止监视器的运行。
try: # 使用无限循环来保持观察器持续运行 while True: # 在每次循环中,使用time.sleep(1)函数暂停1秒钟,以避免过度消耗CPU资源。 time.sleep(1) except KeyboardInterrupt: # 如果在循环中按下Ctrl+C,会引发KeyboardInterrupt异常。 # 在异常处理块中,调用observer.stop()方法停止观察器的运行。 observer.stop()
等待观察器线程的结束
observer.join()
最后,将其封装成一个监听目录的函数 start_monitoring(directory),具体如下所示:
# 监听目录的函数 def start_monitoring(directory): # 创建事件处理器对象 event_handler = MyEventHandler() # 创建观察者对象 observer = Observer() # 将自定义的事件处理器和要监视的目录绑定在一起 observer.schedule(event_handler, directory, recursive=True) # 启动观察器,开始监听目录的变化 observer.start() try: # 使用无限循环来保持观察器持续运行 while True: # 在每次循环中,使用time.sleep(1)函数暂停1秒钟,以避免过度消耗CPU资源。 time.sleep(1) except KeyboardInterrupt: # 如果在循环中按下Ctrl+C,会引发KeyboardInterrupt异常。 # 在异常处理块中,调用observer.stop()方法停止观察器的运行。 observer.stop() # 等待观察器线程的结束 observer.join()
四、最终实现的代码
打开微信,确定自己微信的文件管理路径 E:\WeChat Files\,接着开启监听 start_monitoring("E:/WeChat Files/"),就可以实现接收文件后立马自动取消文件只读属性啦,源码如下所示:
# coding:utf-8 import os,stat import time from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler # 判断文件是否只读 def is_file_read_only(file_path): if os.access(file_path, os.W_OK): # 如果文件或目录具有指定的权限,返回True。 return False else: # 如果文件或目录不具有指定的权限, # 或者检查过程中发生错误,返回False。 return True # 取消文件的只读属性 def unset_file_read_only(file_path): # 获取当前文件的权限标志位 file_stat = os.stat(file_path) # 取消只读属性,将其权限更改为可写 new_mode = file_stat.st_mode | stat.S_IWUSR # 设置新的权限标志位 os.chmod(file_path, new_mode) print("取消文件只读属性:",file_path) # 取消文件只读属性,函数会在文件变化时被调用 def remove_read_only(file_path): # file_path 参数是变化的文件路径 print("文件已变化:", file_path) # 判断文件是否只读 if is_file_read_only(file_path): # 文件是只读的 # 取消文件的只读属性 unset_file_read_only(file_path) else: # 文件不是只读的 pass class MyEventHandler(FileSystemEventHandler): def on_any_event(self, event): print("event_type:",event.event_type) if event.is_directory: # 忽略文件夹的变化 return if event.event_type == 'created' or event.event_type == 'modified': # 只处理新建和修改事件 file_path = event.src_path remove_read_only(file_path) # 监听目录的函数 def start_monitoring(directory): # 创建事件处理器对象 event_handler = MyEventHandler() # 创建观察者对象 observer = Observer() # 将自定义的事件处理器和要监视的目录绑定在一起 observer.schedule(event_handler, directory, recursive=True) # 启动观察器,开始监听目录的变化 observer.start() try: # 使用无限循环来保持观察器持续运行 while True: # 在每次循环中,使用time.sleep(1)函数暂停1秒钟,以避免过度消耗CPU资源。 time.sleep(1) except KeyboardInterrupt: # 如果在循环中按下Ctrl+C,会引发KeyboardInterrupt异常。 # 在异常处理块中,调用observer.stop()方法停止观察器的运行。 observer.stop() # 等待观察器线程的结束 observer.join() if __name__ == "__main__": # 获取要监听的文件夹路径 # NO1:OK directory = 'E:/WeChat Files' # directory = 'E:/WeChat Files/' # NO2:OK # directory = 'E:\\WeChat Files' # NO3:Fail # directory = 'E:\WeChat Files' # 开启监听,满足条件就取消文件只读属性 start_monitoring(directory)
到此这篇关于Python实现监听目录并取消文件只读属性的文章就介绍到这了,更多相关Python监听目录内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!