Have an开发者_StackOverflow中文版 example piece of (Python) code to check if a directory has changed:
import os
def watch(path, fdict):
"""Checks a directory and children for changes"""
changed = []
for root, dirs, files in os.walk(path):
for f in files:
abspath = os.path.abspath(os.path.join(root, f))
new_mtime = os.stat(abspath).st_mtime
if not fdict.has_key(abspath) or new_mtime > fdict[abspath]:
changed.append(abspath)
fdict[abspath] = new_mtime
return fdict, changed
But the accompanying unittest randomly fails unless I add at least a 2 second sleep:
import unittest
import project_creator
import os
import time
class tests(unittest.TestCase):
def setUp(self):
os.makedirs('autotest')
f = open(os.path.join('autotest', 'new_file.txt'), 'w')
f.write('New file')
def tearDown(self):
os.unlink(os.path.join('autotest', 'new_file.txt'))
os.rmdir('autotest')
def test_amend_file(self):
changed = project_creator.watch('autotest', {})
time.sleep(2)
f = open(os.path.join('autotest', 'new_file.txt'), 'a')
f.write('\nA change!')
f.close()
changed = project_creator.watch('autotest', changed[0])
self.assertEqual(changed[1], [os.path.abspath(os.path.join('autotest', 'new_file.txt'))])
if __name__ == '__main__':
unittest.main()
Is stat really limited to worse than 1 second accuracy? (Edit: apparently so, with FAT) Is there any (cross platform) way of detecting more rapid changes?
The proper way is to watch a directory instead of polling for changes.
Check out FindFirstChangeNotification Function.
Watch a Directory for Changes is a Python implementation.
If directory watching isn't accurate enough then probably the only alternative is to intercept file systems calls.
Watchdog: http://packages.python.org/watchdog/quickstart.html
Is a good project to have some multi-platform changes notification.
if this were linux, i'd use inotify. there's apparently a windows inotify equivalent - the java jnotify library has implemented it - but i don't know if there's a python implementation
精彩评论