1

I'm working on a small game with a physical interface that requires me to write a character to the serial port with python every time a particular file in a directory is modified. The file in question is going to be modified probably every 20 - 30 seconds or so while the game is being played.

What is the best method to do this with?

I've been reading a few threads about this including:

How do I watch a file for changes?

How to get file creation & modification date/times in Python?

...but I'm not sure which method to go with. Suggestions?

Edit: Ok, I'd like to use a basic polling method for this. It doesn't have to scale, so small, with no having to upgrade or instal stuff = fine. If anyone has some links or resources on how to use os.path.getmtime() to do this, that would be helpful

ie: How do I go about writing an event loop using this that will notice when the modified date has been changed?

Basically:

  1. Look the time stamp of a file
  2. store that time stamp in a variable called [last_mod]
  3. look at that time stamp again in 5 seconds
  4. if the current time stamp is different than the saved timestamp execute a function and then replace the value of [last_mod] with the current_time stamp

repeat...

Thank You

PS. sorry for the edits.

Community
  • 1
  • 1
mishap_n
  • 578
  • 2
  • 10
  • 23

4 Answers4

1

I've used all of the Python interfaces for notify/fsevents on OSX and at this point I think python-watchdog is the best. Pythonic design, simple to use. No wrestling with weird filesystem masks. It comes with a useful CLI app if you have a bash script too if you're feeling lazy.

https://pypi.python.org/pypi/watchdog

Here's an example I put together a while ago:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import logging
import sys
import time

from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer

logging.basicConfig(level=logging.DEBUG)

class MyEventHandler(FileSystemEventHandler):
    def catch_all_handler(self, event):
        logging.debug(event)

    def on_moved(self, event):
        self.catch_all_handler(event)

    def on_created(self, event):
        self.catch_all_handler(event)

    def on_deleted(self, event):
        self.catch_all_handler(event)

    def on_modified(self, event):
        self.catch_all_handler(event)

path = '/tmp/'

event_handler = MyEventHandler()
observer = Observer()
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    observer.stop()
observer.join()
synthesizerpatel
  • 27,321
  • 5
  • 74
  • 91
  • I only have Python 2.6.1 on my mac ...is this package going to work with that? – mishap_n May 23 '13 at 23:47
  • So I ran the instal for watchdog, but can't run the example. I keep getting errors like: from watchdog.events import FileSystemEventHandler ImportError: No module named watchdog.events Any suggestions on what that might be? – mishap_n May 24 '13 at 00:17
  • I just checked github - https://github.com/gorakhargosh/watchdog/blob/master/src/watchdog/events.py is still in HEAD, and I found a link discussing fsevents in OSX 1.4, so it should be supported even in older versions of the OS. Only thing I can think is maybe you're trying to run the script in the build directory and it's picking up the local dir copy rather than the one you installed. If you installed with easy_install, make sure you used easy_install-2.6 and not the generic system /usr/bin/easy_install. – synthesizerpatel May 24 '13 at 04:47
  • I installed it using pip. I think there's an issue with watchdog and 4.2 of XCode for some reason: https://github.com/gorakhargosh/watchdog/issues/114 Anyways, I'll see if I can get it going. Failing that, do you have any resources for just using os.path.getmtime()? Thanks for the response. – mishap_n May 24 '13 at 13:32
0

This library may be what you want: pyinotify

satoru
  • 31,822
  • 31
  • 91
  • 141
0

By far the simplest thing to do is to poll a file at some interval, checking for its last modification time (os.path.getmtime()). I don't think that it's at all excessive to poll every second, and if it's just one or a small number of processes polling, several times a second isn't crazy. Do that unless you have a compelling reason not to.

In OS X, it's possible to interact with filesystem events, via the FSEvents protocol (at least for HFS+ filesystems). It should be possible to register for a notification event when there is a change on a particular file or directory, which would be the best approach if you needed to do monitoring at a larger scale. I have no experience doing this in python, but one project that claims to help with this is MacFSEvents. Undoubtedly, there's some more direct way to do this using Cocoa APIs with PyObjC.

Truly though, I wouldn't bother with a complicated solution unless you need to observe filesystem events at a large scale. If you're watching a single file that gets changed every 20-30 seconds or so, just poll for changes in your event loop, with a timer to make sure you don't poll too often.

Matt Anderson
  • 19,311
  • 11
  • 41
  • 57
  • Thank you. And yeah its just one file, so a simple / small solution is best. Do you have any resources you could link to, that I can learn to write this little program with using os.path.getmtime()? – mishap_n May 23 '13 at 04:54
0

A simple polling loop would look something like this:

import time
import os

mtime_last = 0
while True:
    time.sleep(5)
    mtime_cur = os.path.getmtime("/path/to/your/file")
    if mtime_cur != mtime_last:
        do_stuff()
    mtime_last = mtime_cur
David Wolever
  • 148,955
  • 89
  • 346
  • 502