monitoring a directory

Tim Golden tim.golden at viacom-outdoor.co.uk
Thu Mar 25 10:09:56 CET 2004


>What would be the most efficient or 'clever' way to monitor a 
>directory 
>for file additions/ modifications on windows?
>
>Currently I'm looping through the directory with a 1 sec delay. But 
>doesn't seem that clever.

There are two methods that I know of (apart from the simple approach you
describe). One is described in this recipe:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/156178

This is simple to use, but falls down a bit if you have more than a few
files in the directory, since it doesn't know what's changed. It's fine if
you're just happy to rescan, say for a file-manager app.

The other method, which is a bit more sophisticated, uses the
recently-added-to-pywin32 win32file.ReadDirectoryChangesW functionality.
Example follows. (I keep meaning to send this up as a recipe, but I never
quite seem to manage). In essence, ReadDirectoryChangesW returns a list of
tuples, each of which is an (action, filename) pair. The actions -- by
experiment -- are held in the ACTIONS dictionary. A rename will always give
a list of two tuples, one with the before and one with the after. Other
compound actions (such as deleting a set of files) may also give a
more-than-one list of tuples. Play around with it. It works.

<code>

import os
import sys
import time

import win32file
import win32con

ACTIONS = {
  1 : "Created",
  2 : "Deleted",
  3 : "Updated",
  4 : "Renamed to something",
  5 : "Renamed from something"
}
## 1 - create
## 2 - delete
## 3 - update (including security change)
## 4 & 5 - before & after on a rename

try: path_to_watch = sys.argv[1] or "."
except: path_to_watch = "."
path_to_watch = os.path.abspath (path_to_watch)

print "Watching %s at %s" % (path_to_watch, time.asctime ())

FILE_LIST_DIRECTORY = 0x0001

hDir = win32file.CreateFile (
    path_to_watch,
    FILE_LIST_DIRECTORY,
    win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
    None,
    win32con.OPEN_EXISTING,
    win32con.FILE_FLAG_BACKUP_SEMANTICS,
    None
)
   
while 1:
  results = win32file.ReadDirectoryChangesW (
    hDir,
    1024,
    True,
    win32con.FILE_NOTIFY_CHANGE_FILE_NAME | 
     win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
     win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
     win32con.FILE_NOTIFY_CHANGE_SIZE |
     win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
     win32con.FILE_NOTIFY_CHANGE_SECURITY,
    None,
    None
  )
  print '-*-*-*'
  for action, file in results:
    full_filename = os.path.join (path_to_watch, file)
    if os.path.isdir (full_filename):
      file_type = 'folder'
    else:
      file_type = 'file'
    print file_type, file, ACTIONS.get (action, "Unknown")

</code>

TJG

________________________________________________________________________
This e-mail has been scanned for all viruses by Star Internet. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________




More information about the Python-list mailing list