Python實(shí)現(xiàn)監(jiān)聽(tīng)目錄并取消文件只讀屬性
一、前言
通過(guò)新版微信接收的文件都被修改了權(quán)限,文件均被設(shè)置為“只讀”?;蛟S這對(duì)于微信來(lái)說(shuō)是挺安全的,但是卻給我們帶來(lái)了不少的麻煩,想修改點(diǎn)東西,必須先取消文件只讀屬性,否者無(wú)法保存。
前段時(shí)間寫過(guò)關(guān)于文件權(quán)限的文章(《python設(shè)置文件只讀與取消文件只讀》,結(jié)合目錄遍歷的知識(shí)(《python3遍歷目錄的三種方法淺談》),再加個(gè)定時(shí)器不斷遍歷 微信接收文件的目錄 ,確實(shí)可以解決問(wèn)題,但不是本文所要講解的,感興趣的小伙伴可以自行嘗試下。
雖然微信版本在持續(xù)更新,但是“文件被設(shè)為只讀”的行為卻沒(méi)有更改,看來(lái)只能用程序打敗程序,監(jiān)聽(tīng)微信接收文件的目錄,接收一個(gè)文件就處理一個(gè)文件的方式,去解決文件只讀的問(wèn)題。
二、第三方監(jiān)聽(tīng)目錄變化庫(kù)
在 Python 的標(biāo)準(zhǔn)庫(kù)中,沒(méi)有直接用于監(jiān)聽(tīng)文件目錄變化的內(nèi)置模塊。有幾個(gè)流行的第三方庫(kù)可以用于監(jiān)聽(tīng)文件目錄的變化,如下:
(1)Watchdog庫(kù)
Watchdog 是一個(gè)功能強(qiáng)大且易于使用的庫(kù),提供了監(jiān)視文件和目錄變化的功能。它支持各種事件,如文件創(chuàng)建、修改、刪除等,并可以在這些事件發(fā)生時(shí)執(zhí)行自定義的回調(diào)函數(shù)。Watchdog庫(kù)在 Python 社區(qū)中廣泛使用,并且有良好的文檔和示例代碼。
(2)Pyinotify庫(kù)
Pyinotify 是一個(gè)與 Linux 內(nèi)核中的 inotify 機(jī)制集成的庫(kù),可以高效地監(jiān)視文件和目錄的變化。它提供了 Pythonic 的 API,可以輕松地處理文件事件。Pyinotify 對(duì)于需要在Linux平臺(tái)上進(jìn)行文件監(jiān)控的任務(wù)非常有用。
(3)Gamin庫(kù)
Gamin 是另一個(gè)用于文件監(jiān)控的庫(kù),它使用 Linux 上的 Gamin 守護(hù)進(jìn)程作為后端。Gamin 庫(kù)提供了一個(gè)簡(jiǎn)單的接口來(lái)監(jiān)視文件和目錄的變化,并可以觸發(fā)相應(yīng)的事件。
(4)PyFilesystem2庫(kù)
PyFilesystem2 是一個(gè)通用的文件系統(tǒng)抽象庫(kù),它可以處理各種文件系統(tǒng)和存儲(chǔ)。雖然它的主要目的是提供一個(gè)統(tǒng)一的 API 來(lái)訪問(wèn)不同類型的文件系統(tǒng),但它也具有監(jiān)視文件變化的功能。
三、監(jiān)聽(tīng)目錄取消文件只讀
為了簡(jiǎn)化開(kāi)發(fā),這里打算采用第三方庫(kù) watchdog 來(lái)實(shí)現(xiàn)我們的需求。
(1)首先,安裝watchdog庫(kù)
pip install watchdog
如果不想污染全局庫(kù),想安裝在虛擬環(huán)境中,可以這樣做:
首先,創(chuàng)建一個(gè)虛擬環(huán)境 chmod_watchdog,virtualenv chmod_watchdog;
其次,激活z虛擬環(huán)境,\chmod_watchdog\Scripts\activate;
接著,安裝 watchdog 庫(kù),pip install watchdog;
完成工作并想要退出虛擬環(huán)境,\chmod_watchdog\Scripts\deactivate
(2)取消文件只讀屬性
判斷文件是否只讀
def is_file_read_only(file_path): if os.access(file_path, os.W_OK): # 如果文件或目錄具有指定的權(quán)限,返回True。 return False else: # 如果文件或目錄不具有指定的權(quán)限, # 或者檢查過(guò)程中發(fā)生錯(cuò)誤,返回False。 return True
取消文件的只讀屬性
def unset_file_read_only(file_path): # 獲取當(dāng)前文件的權(quán)限標(biāo)志位 file_stat = os.stat(file_path) # 取消只讀屬性,將其權(quán)限更改為可寫 new_mode = file_stat.st_mode | stat.S_IWUSR # 設(shè)置新的權(quán)限標(biāo)志位 os.chmod(file_path, new_mode)
(3)事件處理器對(duì)象
創(chuàng)建事件處理器對(duì)象
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()
取消文件只讀屬性,函數(shù)會(huì)在文件變化時(shí)被調(diào)用
def remove_read_only(file_path): # file_path 參數(shù)是變化的文件路徑 print("文件已變化:", file_path) # 判斷文件是否只讀 if is_file_read_only(file_path): # 文件是只讀的 # 取消文件的只讀屬性 unset_file_read_only(file_path) else: # 文件不是只讀的 pass
(4)觀察者對(duì)象
創(chuàng)建觀察者對(duì)象
observer = Observer()
將自定義的事件處理器和要監(jiān)視的目錄綁定在一起
- event_handler:我們定義的自定義事件處理器的實(shí)例;
- directory:需要監(jiān)視的目錄路徑;
- recursive=True 表示要遞歸地監(jiān)視目錄中的子目錄。
observer.schedule(event_handler, directory, recursive=True)
啟動(dòng)觀察器,開(kāi)始監(jiān)聽(tīng)目錄的變化
observer.start()
保持文件監(jiān)視器(Observer)持續(xù)運(yùn)行,并在收到鍵盤中斷信號(hào)(KeyboardInterrupt)時(shí)停止監(jiān)視器的運(yùn)行。
try: # 使用無(wú)限循環(huán)來(lái)保持觀察器持續(xù)運(yùn)行 while True: # 在每次循環(huán)中,使用time.sleep(1)函數(shù)暫停1秒鐘,以避免過(guò)度消耗CPU資源。 time.sleep(1) except KeyboardInterrupt: # 如果在循環(huán)中按下Ctrl+C,會(huì)引發(fā)KeyboardInterrupt異常。 # 在異常處理塊中,調(diào)用observer.stop()方法停止觀察器的運(yùn)行。 observer.stop()
等待觀察器線程的結(jié)束
observer.join()
最后,將其封裝成一個(gè)監(jiān)聽(tīng)目錄的函數(shù) start_monitoring(directory),具體如下所示:
# 監(jiān)聽(tīng)目錄的函數(shù) def start_monitoring(directory): # 創(chuàng)建事件處理器對(duì)象 event_handler = MyEventHandler() # 創(chuàng)建觀察者對(duì)象 observer = Observer() # 將自定義的事件處理器和要監(jiān)視的目錄綁定在一起 observer.schedule(event_handler, directory, recursive=True) # 啟動(dòng)觀察器,開(kāi)始監(jiān)聽(tīng)目錄的變化 observer.start() try: # 使用無(wú)限循環(huán)來(lái)保持觀察器持續(xù)運(yùn)行 while True: # 在每次循環(huán)中,使用time.sleep(1)函數(shù)暫停1秒鐘,以避免過(guò)度消耗CPU資源。 time.sleep(1) except KeyboardInterrupt: # 如果在循環(huán)中按下Ctrl+C,會(huì)引發(fā)KeyboardInterrupt異常。 # 在異常處理塊中,調(diào)用observer.stop()方法停止觀察器的運(yùn)行。 observer.stop() # 等待觀察器線程的結(jié)束 observer.join()
四、最終實(shí)現(xiàn)的代碼
打開(kāi)微信,確定自己微信的文件管理路徑 E:\WeChat Files\,接著開(kāi)啟監(jiān)聽(tīng) start_monitoring("E:/WeChat Files/"),就可以實(shí)現(xiàn)接收文件后立馬自動(dòng)取消文件只讀屬性啦,源碼如下所示:
# 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): # 如果文件或目錄具有指定的權(quán)限,返回True。 return False else: # 如果文件或目錄不具有指定的權(quán)限, # 或者檢查過(guò)程中發(fā)生錯(cuò)誤,返回False。 return True # 取消文件的只讀屬性 def unset_file_read_only(file_path): # 獲取當(dāng)前文件的權(quán)限標(biāo)志位 file_stat = os.stat(file_path) # 取消只讀屬性,將其權(quán)限更改為可寫 new_mode = file_stat.st_mode | stat.S_IWUSR # 設(shè)置新的權(quán)限標(biāo)志位 os.chmod(file_path, new_mode) print("取消文件只讀屬性:",file_path) # 取消文件只讀屬性,函數(shù)會(huì)在文件變化時(shí)被調(diào)用 def remove_read_only(file_path): # file_path 參數(shù)是變化的文件路徑 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) # 監(jiān)聽(tīng)目錄的函數(shù) def start_monitoring(directory): # 創(chuàng)建事件處理器對(duì)象 event_handler = MyEventHandler() # 創(chuàng)建觀察者對(duì)象 observer = Observer() # 將自定義的事件處理器和要監(jiān)視的目錄綁定在一起 observer.schedule(event_handler, directory, recursive=True) # 啟動(dòng)觀察器,開(kāi)始監(jiān)聽(tīng)目錄的變化 observer.start() try: # 使用無(wú)限循環(huán)來(lái)保持觀察器持續(xù)運(yùn)行 while True: # 在每次循環(huán)中,使用time.sleep(1)函數(shù)暫停1秒鐘,以避免過(guò)度消耗CPU資源。 time.sleep(1) except KeyboardInterrupt: # 如果在循環(huán)中按下Ctrl+C,會(huì)引發(fā)KeyboardInterrupt異常。 # 在異常處理塊中,調(diào)用observer.stop()方法停止觀察器的運(yùn)行。 observer.stop() # 等待觀察器線程的結(jié)束 observer.join() if __name__ == "__main__": # 獲取要監(jiān)聽(tīng)的文件夾路徑 # NO1:OK directory = 'E:/WeChat Files' # directory = 'E:/WeChat Files/' # NO2:OK # directory = 'E:\\WeChat Files' # NO3:Fail # directory = 'E:\WeChat Files' # 開(kāi)啟監(jiān)聽(tīng),滿足條件就取消文件只讀屬性 start_monitoring(directory)
到此這篇關(guān)于Python實(shí)現(xiàn)監(jiān)聽(tīng)目錄并取消文件只讀屬性的文章就介紹到這了,更多相關(guān)Python監(jiān)聽(tīng)目錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python Web日志管理與監(jiān)控實(shí)踐指南
這篇文章主要介紹了Python Web日志管理與監(jiān)控實(shí)踐指南,文中通過(guò)代碼示例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-09-09python基于tkinter制作無(wú)損音樂(lè)下載工具(附源碼)
這篇文章主要介紹了python基于tkinter制作無(wú)損音樂(lè)下載工具(附源碼),幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下2021-03-03在python的類中動(dòng)態(tài)添加屬性與生成對(duì)象
這篇文章給大家介紹了如何在python的類中動(dòng)態(tài)添加屬性和生成對(duì)象,文中通過(guò)幾個(gè)方面來(lái)進(jìn)行介紹,對(duì)這感興趣的朋友們可以學(xué)習(xí)學(xué)習(xí)。2016-09-09python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5滾動(dòng)條控件QScrollBar詳細(xì)使用方法與實(shí)例
這篇文章主要介紹了python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5滾動(dòng)條控件QScrollBar詳細(xì)使用方法與實(shí)例,需要的朋友可以參考下2020-03-03OpenCV學(xué)習(xí)方框?yàn)V波實(shí)現(xiàn)圖像處理代碼示例
這篇文章主要為大家介紹了OpenCV學(xué)習(xí)如何使用方框?yàn)V波實(shí)現(xiàn)對(duì)圖像處理代碼示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-10-107個(gè)流行的Python強(qiáng)化學(xué)習(xí)算法及代碼實(shí)現(xiàn)詳解
目前流行的強(qiáng)化學(xué)習(xí)算法包括?Q-learning、SARSA、DDPG、A2C、PPO、DQN?和?TRPO。這些算法已被用于在游戲、機(jī)器人和決策制定等各種應(yīng)用中,本文我們將對(duì)其做一個(gè)簡(jiǎn)單的介紹,感興趣的可以學(xué)習(xí)一下2023-01-01python線程池 ThreadPoolExecutor 的用法示例
這篇文章主要介紹了python線程池 ThreadPoolExecutor 的用法示例,幫助大家更好得理解和使用python線程池,感興趣的朋友可以了解下2020-10-10python爬取網(wǎng)易云音樂(lè)評(píng)論
這篇文章主要為大家詳細(xì)介紹了python爬取網(wǎng)易云音樂(lè)評(píng)論,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11