2015-08-19 3 views
4

Я использую модуль сторожевого таймера Python на сервере Windows 2012 для мониторинга новых файлов, появляющихся на общем диске. Когда watchdog замечает новый файл, он запускает процесс восстановления базы данных.Pidon watchdog windows wait до завершения копирования

Однако, похоже, что сторожевой таймер попытается восстановить файл, который он создал, и не дожидаться завершения копирования файла на общий диск. Таким образом, я изменил событие на on_modified, но есть два события on_modified: один, когда файл изначально копируется, и один, когда он закончен, копируется.

Как я могу обработать два события on_modified, чтобы они срабатывали только при завершении копирования файла на общий диск?

Что происходит, когда несколько файлов копируются на общий диск одновременно?

Вот мой код

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

class NewFile(FileSystemEventHandler): 
    def process(self, event): 
     if event.is_directory: 
      return 

    if event.event_type == 'modified':    
     if getext(event.src_path) == 'gz': 
      load_pgdump(event.src_path) 

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

def getext(filename): 
    "Get the file extension" 
    file_ext = filename.split(".",1)[1] 
    return file_ext 

def load_pgdump(src_path):  
    restore = 'pg_restore command ' + src_path 
    subprocess.call(restore, shell=True) 

def main(): 
    event_handler = NewFile() 
    observer = Observer() 
    observer.schedule(event_handler, path='Y:\\', recursive=True) 
    observer.start() 

    try: 
     while True: 
      time.sleep(1) 
    except KeyboardInterrupt: 
     observer.stop() 
    observer.join() 

if __name__ == '__main__': 
    main() 
+0

Как вы передаете файл? Можете ли вы также загрузить контрольную сумму? Идея сделать восстановление БД без него страшно для меня. Если вы переходите по маршруту «проверка, задержка, проверка еще раз», вы идете с оптимизмом. –

ответ

0

Я хотел бы добавить комментарий, как это не ответ на ваш вопрос, но другой подход ... но я не хватает респ еще. Вы можете попробовать контролировать размер файла, если он перестанет меняться, вы можете предположить, что копия завершена:

copying = True 
size2 = -1 
while copying: 
    size = os.path.getsize('name of file being copied') 
    if size == size2: 
     break 
    else: 
     size2 = os.path.getsize('name of file being copied') 
     time.sleep(2) 
1

У меня была аналогичная проблема недавно с сторожевым псом. Довольно простой, но не очень умный способ обхода - проверить изменение размера файла в цикле while, используя двухэлементный список, один для «прошлого», один для «сейчас». После того, как значения равны, копирование завершено.

Редактировать: примерно так.

past = 0 
now = 1 
value = [past, now] 
while True: 
    # change 

    # test 
    if value[0] == value[1]: 
     break 
    else: 
     value = [value[1], value[0]] 
3

В вашем событии on_modified просто подождите, пока файл не будет скопирован, просмотрев размер файла.

Предлагая Simpler Loop:

historicalSize = -1 
while (historicalSize != os.path.getsize(filename)): 
    historicalSize = os.path.getsize(filename) 
    time.sleep(1) 
print "file copy has now finished" 
0

Я использую следующий код, чтобы ждать, пока файл скопирован (для Windows, только):

from ctypes import windll 
import time 

def is_file_copy_finished(file_path): 
    finished = False 

    GENERIC_WRITE   = 1 << 30 
    FILE_SHARE_READ  = 0x00000001 
    OPEN_EXISTING   = 3 
    FILE_ATTRIBUTE_NORMAL = 0x80 

    if isinstance(file_path, str): 
     file_path_unicode = file_path.decode('utf-8') 
    else: 
     file_path_unicode = file_path 

    h_file = windll.Kernel32.CreateFileW(file_path_unicode, GENERIC_WRITE, FILE_SHARE_READ, None, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, None) 

    if h_file != -1: 
     windll.Kernel32.CloseHandle(h_file) 
     finished = True 

    print 'is_file_copy_finished: ' + str(finished) 
    return finished 

def wait_for_file_copy_finish(file_path): 
    while not is_file_copy_finished(file_path): 
     time.sleep(0.2) 

wait_for_file_copy_finish(r'C:\testfile.txt') 

Идея заключается в том, чтобы попытаться открыть файл для записи с режимом чтения разделов. Это не удастся, если кто-то еще напишет.

Enjoy;)

Смежные вопросы