如何在Python中查找修改后的文件
我想要监视一个文件夹并查看是否添加了新文件或修改了现有文件。问题是,并不能保证我的程序会一直运行(因此,基于inotify
的解决方案可能不适用于此)。我需要缓存最后一次扫描的状态,然后使用下一次扫描,在处理文件之前我需要将它与最后一次扫描进行比较。如何在Python中查找修改后的文件
在Python 2.7中实现此功能有哪些选择?
注1:文件的处理很昂贵,所以我试图处理那些在此期间未修改的文件。所以,如果文件只是重命名(而不是文件内容的改变),我还想检测并跳过处理。注2:我只对Linux解决方案感兴趣,但如果添加其他平台的答案,我不会抱怨。
有几种方法可以检测文件中的更改。有些人比其他人更容易被愚弄。这听起来不像是一个安全问题;更多 如同诚信假设,你只需要检测变化而不需要 不得不智胜对手。
你可以看看时间戳。如果文件没有被重命名,这是检测更改的好方法 。如果它们被重新命名,单独的时间戳就不足以可靠地将另一个文件告诉一个文件。 os.stat
会告诉你 上次修改文件的时间。
您可以查看inode,例如ls -li
。如果更改涉及创建新文件并删除旧文件,则文件的inode编号可能会更改为 ;例如,这是 emacs
通常如何更改文件。尝试使用组织使用的标准工具更改文件 ,并在 之前和之后比较inode;但请记住,即使这次没有改变,它在某些情况下可能会改变。 os.stat
会告诉你inode 号码。
您可以查看文件的内容。 cksum
计算一个文件上的一个小的CRC校验和 ;如果有人愿意,很容易击败。程序 等sha256sum
计算安全散列;在不更改这种散列的情况下更改文件 是不可行的。如果文件很大,这可能会很慢。 hashlib
模块将计算几种安全哈希。
如果一个文件被重命名和改变,其索引节点号的变化,这将 可能非常难以与它曾经 是,该文件匹配起来,除非该文件中的数据包含某种一成不变的和 唯一标识符。
考虑并发性。程序运行时,有人可能会更改 文件吗?谨防竞态条件。
我可能会用某种sqlite解决方案,比如写最后的轮询时间。 然后在每个这样的轮询中,按last_modified_time(mtime)对文件进行排序,并获得所有mtime大于以前的轮询的人(如果你坚持没有,那么这个值将从sqlite或某种文件中取出这样的分贝的要求)。
监控新文件并不困难 - 只保留目录中所有文件的inode列表或数据库。一个新文件将引入一个新的inode。这也将帮助您避免处理重命名的文件,因为inode在重命名时不会更改。
更难的问题是监视文件更改。如果您还为每个inode存储文件大小,那么明显更改的大小表示更改的文件,并且您不需要打开并处理该文件即可知道该文件。但对于(a)之前已记录的inode和(b)大小与之前相同的文件,您需要处理文件(例如,计算校验和)以确定它是否已更改。
我建议作弊和使用系统find命令。例如,以下内容将查找在最近60分钟内修改或创建的所有Python文件。使用ls
输出可以确定是否需要进一步检查。
$ echo beer > zoot.py
$ find . -name '*.py' -mmin -60 -type f -ls
1973329 4 -rw-r--r-- 1 johnm johnm 5 Aug 30 15:17 ./zoot.py
它会是远不及复杂的,如果你能保证你的程序将运行所有的时间,不是存储时,它不是,然后试图重新扫描更改... – 2014-08-30 21:43:46
@JonClements是的,但不幸的是这是不可能的。基本上,用户确定程序何时运行。这是该计划的性质。 – 2014-08-30 21:52:25
只需创建一个包含文件名和最后修改日期的字典(可以使用'os.stat()'获得),然后将其写入一个文件并在每次运行时读取它 – wnnmaw 2014-08-30 22:10:46