首页 > 解决方案 > 使用python看门狗检测移动目录的文件

问题描述

我正在尝试制作一个 python 脚本来监视带有看门狗的文件夹并更新降价文档中的链接。我目前正在使用 python 看门狗库来查看我的笔记本文件夹,但我遇到了问题。当我重命名文件时,它会触发on_moved预期的功能,但是如果我将文件从一个目录移动到另一个目录,它会触发该on_deleted功能,然后很快就会调用该on_created功能。对于我的项目,如果文件被删除或刚刚移动,我希望能够做单独的事情。目前我不知道如何区分正在删除的文件和刚刚移动的文件。

下面是我尝试使用的代码。

# Import all plugins and configure them
import time
import os
import fileinput
import logging
import watchdog.events
import watchdog.observers
from lazydog.handlers import HighlevelEventHandler
from watchdog.observers import Observer  
from watchdog.events import PatternMatchingEventHandler

# Define all variables
Notebooks = "C:\\Notebooks"
file_type = ".md"
alert_file = "C:\\Notebooks\\ALERT.md"
last_deleted_path = "NOT SET YET"
last_deleted_file = "NOT SET YET"
last_created_path = "NOT SET YET"
last_created_file = "NOT SET YET"
last_renamed_path = "NOT SET YET"
last_renamed_file = "NOT SET YET"
current_path = "NOT SET YET"
current_file = "NOT SET YET"
replaced_link = "NOT SET YET"
replacement_link = "NOT SET YET"

class Handler(watchdog.events.PatternMatchingEventHandler):
    def __init__(self): 
        # Set the patterns for PatternMatchingEventHandler 
        watchdog.events.PatternMatchingEventHandler.__init__(self, patterns=['*.md'], ignore_directories=False, case_sensitive=False)

    def on_deleted(self, event):
        # Enter variables in scope
        global last_deleted_path
        global last_deleted_file

        print("The file [" + event.src_path + "] was deleted.")
        last_deleted_path = event.src_path                      # Log the last deleted path to the last_deleted_path variable
        last_deleted_file = os.path.basename(event.src_path)    # Log the last deleted file not including the path

        replaced_link = last_deleted_path                       # We want to replace this link      
        created()
    def on_created(self, event):
        # Enter variables in scope
        global last_deleted_path
        global last_deleted_file
        global last_created_path
        global last_created_file

        print(event.src_path + " triggered on_created")
        last_created_path = event.src_path                      # Log the last deleted path to the last_deleted_path variable
        last_created_file = os.path.basename(event.src_path)    # Log the last deleted file not including the path   

        if last_deleted_file == last_created_file:              # The file was moved and not a new file
            print("\n")
            print("The file: " + last_created_file + " was moved from " + last_deleted_path + " to " + last_created_path)
            print("\n")
            search_and_replace()
        else:                                                   # This is a brand new file
            nothing()
    def on_modified(self, event):
        nothing()
    def on_moved(self, event):          # When a event is "moved" it is renamed. When a event is moved it is deleted then created.
        # Enter variables in scope
        global last_renamed_path
        global last_renamed_file
        global current_path
        global current_file

        print(event.src_path + " triggered on_moved")
        last_renamed_path = event.src_path                      # Log the last renamed path to the last_renamed_path variable
        last_renamed_file = os.path.basename(event.src_path)    # Log the last renamed file not including the path
        current_path = event.dest_path                          # Log the current path to the current_path variable
        current_file = os.path.basename(event.dest_path)        # Log the current file not including the path

        search_and_replace()

if __name__ == "__main__": 
    src_path = Notebooks
    event_handler = Handler() 
    observer = watchdog.observers.Observer() 
    observer.schedule(event_handler, path=src_path, recursive=True) 
    observer.start() 
    try: 
        while True: 
            time.sleep(1) 
    except KeyboardInterrupt: 
        observer.stop() 
        observer.join()

def search_and_replace():
    files = []
    for r, d, f in os.walk(Notebooks):                          # For all the root, directories, and files in path... (r=root, d=directories, f = files) put them in files
        for files in f:
            if file_type in files:
                files.append(os.path.join(r, files))
    for i in files:                                             # For all the files search for the link and replace it
        with fileinput.FileInput(i, inplace=True) as file:
            for line in file:
                print(line.replace(replaced_link, replacement_link), end='')
def search_and_alert():
    files = []
    for r, d, f in os.walk(Notebooks):                          # Scan recursivly all the files in the target notebook folder (r=root, d=directories, f = files)
        for files in f:
            if file_type in files:
                files.append(os.path.join(r, files))
    for i in files:                                             # For all the .md files search for the link
        reading_file = open(i, "r")                             # Open the file
        data = reading_file.read()                              # Read content of the file
        occurrences = data.count(last_deleted_path)             # Get number of occurrences of the link in the file

        if occurrences != 0:                                    # This note has at least one deleted link, so append a note to ALERT.md
            file1 = open(alert_file, "a")
            file1.write("\n\nThe file " + last_deleted_path + " was deleted. This affects the file(s) " + files + ". The link occured " + occurrences + " times.") 
            file1.close()
        else:                                                   # This note does not have the deleted link so just keep going
            continue
def created():
    if last_deleted_file == last_created_file:              # This will be false if the file was moved
        nothing()
    else:                                                   # This file was just deleted not moved
        search_and_alert()
def nothing():
    print()

提前感谢您的所有帮助:)

-卡尔

标签: pythonfilefilesystemspython-watchdog

解决方案


您可以存储文件名与删除时间的哈希图。
每当删除文件时,您都可以在 hashmap 中创建一个条目。
当调用 create listener 时,我们可以检查该文件的删除是否发生在 <0.5 秒之前。如果是,那么这是一个举动。


推荐阅读