0

Have an 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?

mavnn
  • 9,101
  • 4
  • 34
  • 52
  • See http://stackoverflow.com/questions/943503/python-getting-file-modification-times-with-greater-resolution-than-a-second. – unwind Oct 09 '09 at 09:22
  • Thanks, that answers the first question (my google-fu was obviously lacking when I searched earlier). I'm still interested in alternative methods (if there are any). – mavnn Oct 09 '09 at 09:26

3 Answers3

1

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.

Nick Dandoulakis
  • 42,588
  • 16
  • 104
  • 136
  • This is something I looked into, but as stated above I need this code to run cross platform (XP and Ubuntu specifically). I may have to give up and vary the mechanism based on os. – mavnn Oct 09 '09 at 09:46
1

Watchdog: http://packages.python.org/watchdog/quickstart.html

Is a good project to have some multi-platform changes notification.

andrea_crotti
  • 3,004
  • 2
  • 28
  • 33
  • Answering to myself, I just discovered that QT does it too, http://doc.qt.nokia.com/latest/qfilesystemwatcher.html Then you can use pyqt or pyside for a nice python interface. – andrea_crotti Dec 09 '11 at 16:00
0

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

Igor Serebryany
  • 3,307
  • 3
  • 29
  • 41