【问题标题】:How can I get changes in a directory in Python如何在 Python 中获取目录中的更改
【发布时间】:2020-06-21 16:22:51
【问题描述】:

我正在尝试获取目录中的最后一次更改,而不仅仅是最后修改的文件。

到目前为止我有这个代码:

import pathlib
import logging

# Set logging level
logging.basicConfig(level=logging.DEBUG)

# Define some paths
source_path = pathlib.Path("U:")

logging.info(f"Source directory is {source_path}")

# Latest path
latest_path = max(source_path.glob('*'),
                  key=lambda path: path.stat().st_ctime)
last_path = None

while True:
    try:
        # Latest path
        latest_path = max(source_path.glob('*'),
                          key=lambda path: path.stat().st_ctime)
    except FileNotFoundError:
        pass
    if not latest_path == last_path:
        logging.info(f"Last changed path is {latest_path}")
        last_path = latest_path

它的作用是打印目录中的最新更改(当前为U:

这是一些示例输出:

INFO:root:Source directory is U:
INFO:root:Last changed path is U:Website Downloader
INFO:root:Last changed path is U:New Text Document.txt <-- Created it
INFO:root:Last changed path is U:hi.txt <-- Renamed it
INFO:root:Last changed path is U:Website Downloader <-- Deleted hi.txt
INFO:root:Last changed path is U:New folder <-- Created it
INFO:root:Last changed path is U:hi <-- Renamed it
INFO:root:Last changed path is U:Website Downloader <-- Deleted hi (directory)

它遗漏了一些内容,例如保存基目录 (U:) 中文件的更改、目录中的新文件、修改文件和删除文件。

我想让它说,比如:

INFO:root:Source directory is U:
INFO:root:File created: U:New Text Document.txt 
INFO:root:File modified: U:New Text Document.txt
INFO:root:File deleted: U:New Text Document.txt
INFO:root:Directory created: U:New Folder
INFO:root:File created: U:New Folder\New Text Document.txt 
INFO:root:File modified: U:New Folder\New Text Document.txt 
INFO:root:File deleted: U:New Folder\New Text Document.txt 
INFO:root:Directory created: U:New Folder\New Folder
INFO:root:Directory created: U:New Folder\New Folder\New Folder
INFO:root:Directory deleted: U:New Folder\New Folder\New Folder
INFO:root:Directory deleted: U:New Folder

这在 Python 中是否可行?

提前致谢

【问题讨论】:

  • 我建议您使用看门狗而不是定制的解决方案。您肯定会在网上找到示例代码。看门狗或其他此类库不会进行轮询,而是依靠操作系统当场通知。
  • 我将研究看门狗模块,但由于@alaniwi 花时间生成了一些工作代码,我会给他打勾。
  • 我不担心获得支持。我只是相信操作系统支持的事件驱动解决方案是一个更好的解决方案。
  • @Tarik,我什么时候说过要放弃投票了?如果我发疯了,请纠正我,但我从来没有说过放弃投票。 alaniwi 花了宝贵的时间用代码而不是模块的链接来回答我的问题,所以我会接受他的回答。
  • 哦,顺便说一句,我现在正在使用看门狗模块。

标签: python file directory last-modified


【解决方案1】:

对于它的价值,如果您需要使用轮询扫描器,这里有一个实现。受限于关于性能的明显警告,并且它不会注意到在轮询间隔之间再次出现和消失的文件。

import time
import pathlib
import logging

logging.basicConfig(level=logging.DEBUG)


def get_paths(path):
    answer = {}
    for x in pathlib.Path(path).rglob("*"):
        try:
            answer[str(x)] = (x.stat().st_ctime, x.is_dir())
        except FileNotFoundError:
            pass
    return answer


def log(name, is_dir, action):
    descrip = "Directory" if is_dir else "File"
    logging.info("{} {}: {}".format(descrip, action, name))
    

def scan(top_dir, sleep_time):

    old_paths = get_paths(top_dir)
    s_old_paths = set(old_paths)

    while True:
        time.sleep(sleep_time)
        new_paths = get_paths(top_dir)
        s_new_paths = set(new_paths)
        cre_names = s_new_paths - s_old_paths
        del_names = s_old_paths - s_new_paths

        for name in cre_names:
            _, is_dir = new_paths[name]
            log(name, is_dir, "created")

        for name in del_names:
            _, is_dir = old_paths[name]
            log(name, is_dir, "deleted")

        for name in s_old_paths & s_new_paths:
            new_time, is_dir = new_paths[name]
            old_time, _ = old_paths[name]
            if new_time != old_time:
                log(name, is_dir, "modified")

        old_paths = new_paths
        s_old_paths = s_new_paths
    

top_dir = "U:"
sleep_time = 10
scan(top_dir, sleep_time)

【讨论】:

  • 非常感谢您花时间回答我的问题!我会将其标记为正确答案,因为其中包含 实际 代码并且它可以满足我的需要
  • @Unsigned_Arduino 不客气。我没有写太多的描述,但正如你所看到的,它使用path_name: (ctime, is_dir) 的字典,并且每次都将当前与前一个进行比较。显然,如果实际实施,事件驱动的东西有可能成为更好的解决方案。
【解决方案2】:

您需要的是一个事件驱动的文件夹观察程序库。例如https://pypi.org/project/watchdog/

更多,谷歌出python文件夹观察者

它可能取决于操作系统。

【讨论】:

  • 感谢您抽出宝贵时间回答我的问题!我将@alaniwi 的答案标记为答案,因为它有工作代码,但我会查看看门狗库!
【解决方案3】:

这绝对是可能的,我的意思是,一切皆有可能!不过它可能有点复杂,所以我建议你使用像 watchdog 这样的库,它可以连接到操作系统的文件系统事件监控 thingamabob。

【讨论】:

  • 感谢您抽出宝贵时间回答我的问题!我会检查看门狗模块。
  • 另外,1+ 用于使用科学术语 thingamabob。
猜你喜欢
  • 1970-01-01
  • 2012-06-14
  • 2019-01-05
  • 2012-12-25
  • 2021-05-24
  • 2012-10-22
  • 2020-03-05
  • 1970-01-01
相关资源
最近更新 更多