The essence of the program: check the files for the latest update, and if they were changed, then copy them to another folder.

So the problem is that I have a list of files obtained using the ** os.listdir (path) * function. But its contents are just text. How can I bind elements to real files?

  • Please give a definition: проверить файлы на последнее изменение . Is this a check on the date the file was modified, or a check for content changes or something else? - MaxU
  • On the date the file was modified. - PoruchikRzhevskiy
  • and what will be the reference date - the time of the last check? - MaxU
  • Date of the previous change stored in the list / dictionary. I want to make sure that every 30 seconds it is checked whether the file has changed. PS I have little experience, I began to study Python only recently. - PoruchikRzhevskiy
  • I think you need a Watchdog module - MaxU

5 answers 5

For the sake of completeness, there is not enough response with https://pypi.python.org/pypi/inotify

 import logging import inotify.adapters _DEFAULT_LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' _LOGGER = logging.getLogger(__name__) def _configure_logging(): _LOGGER.setLevel(logging.DEBUG) ch = logging.StreamHandler() formatter = logging.Formatter(_DEFAULT_LOG_FORMAT) ch.setFormatter(formatter) _LOGGER.addHandler(ch) def _main(): i = inotify.adapters.Inotify() i.add_watch('/tmp') try: for event in i.event_gen(): if event is not None: (header, type_names, watch_path, filename) = event _LOGGER.info("WD=(%d) MASK=(%d) COOKIE=(%d) LEN=(%d) MASK->NAMES=%s " "WATCH-PATH=[%s] FILENAME=[%s]", header.wd, header.mask, header.cookie, header.len, type_names, watch_path, filename) finally: i.remove_watch('/tmp') if __name__ == '__main__': _configure_logging() _main() 

i.event_gen() yield of file change events in the directory.

  • perfect solution! it’s just a pity that it will work only for Linux kernel as of version 2.6 - MaxU
  • @MaxU inotify is also available in later versions. or you in vindovs? - eri
  • I’m more about Windows ... I wonder if it will work under macOS X ? - MaxU
  • one
    and under Windows and Mac there are such mechanisms - eri

Something like this:

 import os import time for fname in os.listdir(): t = os.path.getmtime(fname) print ("modification time of '{}' is {}".format(fname, time.ctime(t))) current_mtime[fname] = t if t > last_mtime[fname]: do_something(fname) last_mtime = current_mtime 

    Sitting on Linux, you can not make crutches, but use the opportunity provided by the OS — inotify and a special daemon that facilitates the work — incron . It works incron extremely easy and pleasant. For example, a line from the incrontab file:

     /home IN_CREATE /home/user/my_cool_python_script.py $# 

    means that when a directory or file is created in the / home directory, the specified script will be called with a parameter indicating the name of the file with which the observed event occurred.

    • watchmedo works on Linux, macOS and Windows - jfs

    Here is a working version using Watchdog .

    I slightly modified this example. (C) Bruno Rocha

    watch_for_changes.py:

     from __future__ import print_function import os import sys import time import shutil from watchdog.observers.polling import PollingObserverVFS from watchdog.events import PatternMatchingEventHandler class MyHandler(PatternMatchingEventHandler): #patterns = ["*.*", ".*"] def __init__(self, target_dir, **kwargs): PatternMatchingEventHandler.__init__(self, **kwargs) self._target_dir = target_dir def process(self, event): """ event.event_type 'modified' | 'created' | 'moved' | 'deleted' event.is_directory True | False event.src_path path/to/observed/file """ if not event.is_directory: # the file will be processed there print('{} {} --> {}'.format(event.src_path, event.event_type, self._target_dir)) shutil.copy(event.src_path, self._target_dir) def on_modified(self, event): self.process(event) def on_created(self, event): self.process(event) if __name__ == '__main__': args = sys.argv[1:] source_dir = args[0] target_dir = args[1] observer = PollingObserverVFS(stat=os.stat, listdir=os.listdir, polling_interval=30) observer.schedule(MyHandler(target_dir, patterns=['*.*','*','.*']), path=source_dir) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join() 

    How to call:

     python watch_for_changes.py c:\source_dir c:\target_dir 

    PS In theory, this should work on any platform where Python is supported, in practice I checked it only under Windows ...

    • as self-learning, I suggest adding parsing of command line arguments — you can also specify several monitoring directories at once, set polling_interval , patterns , etc. ... - MaxU

    If we are talking about files, you can do it with the help of a dictionary:

     import os fdict = {} path = "путь_к_директории_с_файлами" files = os.listdir(path) for i in files: if isfile(path+i): fdict[i] = open(path+i,'r') 

    This script creates a dictionary of files with keys - their names. An example of choosing a file from it:

     fdict["имя_файла"]