3 min read

Published:  
Updated:  

Determine if a file has been modified in Python

Contents

  1. Introduction
  2. TLDR
  3. Full Code

Introduction

I have to say this isn’t the most advanced problem to solve and the code snippets below are probably not the most efficient way of doing things. That said this worked for me so it might work for you.

I recently needed a way of determining when a file was modified. So I created a file watcher/poller using Python. The class works by checking the files modified time (returned as seconds) against the modified time when the script started or last time it was modified. If they are different then the file was changed and the call-back function is called. Basic overview complete now some code.

First some imports:

import os
import time
import traceback

Create the class and define the init method:

class FileWatcher:
    def __init__(self, watch_path, callback):
        self.watch_path = watch_path
        self.callback = callback
        self.modifiedOn = os.path.getmtime(file_path)
        self.counter = 0

When the class instantiated it needs to be provided, the path to the file to watch for changes, and a call-back which is a function that will be run when the file is modified. Next is the watching function I named “start”

    def start(self):
        try:
            while True:
                time.sleep(10)
                modified = os.path.getmtime(self.file_path)
                if modified != self.modifiedOn or self.counter >= 100:
                    self.modifiedOn = modified
                    self.counter = -1
                    if self.callback():
                        break
                else:
                    print("File Not Changed")
                    self.counter += 1
        except Exception as e:
            print(traceback.format_exc())

This function is a try-except block with a while true loop nested inside, this is where the modified time is fetched and compared to the stored modified time. The exception will catch errors if the file isn’t found. If the file modified time and the stored modified time don’t match the call-back is executed. There is also a counter with increase every time the loop run without the file being modified, this is used to force run the call-back as a backup if a modification was missed or something odd happens with the modified time.

To start the file watcher, instantiate the class with all the requirements and then run the start function.

 file_watcher_handler = FileWatcher("Test.txt", read_file)
 file_watcher_handler.start()

The call-back can be anything you like, a file reader or backup function for example. It would be a good idea to include some error catching for permissions issues if the user still has the file open. This might be useful.

def read_file():
    success = False
    try:
        with open("test.txt") as file_object:
            contents = file_object.read()
            print(contents)
            success = True
    except PermissionError:
        print("Permission Error - Can't open the file")
    finally:
        if not success:
            time.sleep(10)
            read_file()

Hopefully this was useful, Enjoy!

TLDR

This python class will watch a file for modification. When the files is changed the call-back function is run.

Full Code

import os
import time
import traceback


class FileModified:
    def __init__(self, watch_path, callback):
        self.watch_path = watch_path
        self.callback = callback
        self.modifiedOn = os.path.getmtime(watch_path)
        self.counter = 0

    def start(self):
        try:
            while True:
                time.sleep(10)
                modified = os.path.getmtime(self.file_path)
                if modified != self.modifiedOn or self.counter >= 100:
                    self.modifiedOn = modified
                    self.counter = -1
                    if self.callback():
                        break
                else:
                    print("File Not Changed")
                    self.counter += 1
        except Exception as e:
            print(traceback.format_exc())


def read_file():
    success = False
    try:
        with open("test.txt") as file_object:
            contents = file_object.read()
            print(contents)
            success = True
    except PermissionError:
        print("Permission Error - Can't open the file")
    finally:
        if not success:
            time.sleep(10)
            read_file()