2012-03-13 5 views
0

Доброе утро, Какова лучшая стратегия проверки, когда большой файл o большой каталог закончил копировать? Я хочу подождать, пока файл полностью завершит копирование. Есть ли пример кода в qQt или PyQt - проверьте, используется ли файл другим процессом. Подождите, пока не закончите копию

Я работаю над mac os x.

благодаря

Update

Я использую QFileSystemWatcher. проблема в том, что я получаю уведомление об изменении файла или каталога, когда o копирует его. Таким образом, пользователь копирует большую папку (внутри многих файлов), запускается процесс копирования операционной системы, занимает 5 минут, но в то же время мое приложение получает уведомление об изменении файла. Это проблема, потому что, когда я получаю уведомление об изменении, мое приложение запускает некоторые операции над этими файлами, но копия уже выполняется !!!!

+0

FYI: Недавно я узнал, что QFileSystemWatcher (работает в Windows) работает с сетевыми ресурсами, а также если серверы запускают окна. Он не будет корректно работать для сетевых ресурсов, которые выполняются на сервере linux со старой версией samba - dunno, если он работает правильно с обновленной версией samba. – smerlin

ответ

0

Я думаю, что QFileSystemWatcher правильный старт для вас, чтобы добраться до точки наблюдения за изменениями, но, как вы обнаружили, эти изменения ANY изменения. С этого момента, я думаю, вам должно быть достаточно просто проверить время модификации файла.

Вот простой пример класса Watcher, который позволит вам указать файл для мониторинга и посмотреть, было ли оно изменено по истечении заданного времени. Он может запустить обратный вызов или излучать сигнал, что любой человек может смотреть:

import os.path 
import time 

from PyQt4 import QtCore 

class Watcher(QtCore.QObject): 

    fileNotModified = QtCore.pyqtSignal(str) 

    MOD_TIME_DIFF = 5 #seconds 

    def __init__(self, aFile, callback=None, checkEvery=5): 
     super(Watcher, self).__init__() 

     self.file = aFile 
     self.callback = callback 

     self._timer = QtCore.QTimer(self) 
     self._timer.setInterval(checkEvery*1000) 
     self._timer.timeout.connect(self._checkFile) 

    def _checkFile(self): 
     diff = time.time() - os.path.getmtime(self.file) 
     if diff > self.MOD_TIME_DIFF: 
      self._timer.stop() 

      self.fileNotModified.emit(self.file) 

      if self.callback: 
       self.callback() 

    def start(self): 
     self._timer.start() 

    def stop(self): 
     self._timer.stop() 

Пример использования его:

def callbackNotify(): 
    print "Callback!" 

def signalNotify(f): 
    print "Signal: %s was modified!" % f 

# You could directly give it a callback 
watcher = Watcher("/path/to/file.file", callback=callbackNotify) 
# Or could use a signal 
watcher.fileNotModified.connect(signalNotify) 
# tell the watcher timer to start checking 
watcher.start() 

## after the file hasnt been modified in 5 seconds ## 
# Signal: /path/to/file.file was modified! 
# Callback! 
0

Попробуйте использовать QtConcurrent рамки. В частности, проверьте QFuture и QFutureWatcher. Вы можете выполнять асинхронные операции копирования внутри объекта QFuture и отслеживать его прогресс через сигналы и слоты с наблюдателем.

bool copyFunction() { 
    // copy operations here, return true on success 
} 

MyHandlerClass myObject; 
QFutureWatcher<bool> watcher; 
connect(&watcher, SIGNAL(finished()), &myObject, SLOT(handleFinished())); 
QFuture<bool> future = QtConcurrent::run(copyFunction); 
+0

проблема в том, что это не мое приложение, которое копирует файл, а внешнее приложение. Итак, Мое приложение должно подождать, пока внешнее приложение не завершит копирование в каталог, который мое приложение отслеживает для записи файла или каталога изменений. – paganotti

+0

В этом случае вы можете использовать QFileSystemWatcher: http://qt-project.org/doc/qt-4.8/qfilesystemwatcher.html внимательно прочитать заметки для конкретных вопросов платформы. – Masci

+0

Я использую QFileSystemWatcher. проблема в том, что я получаю уведомление об изменении файла или каталога, когда o копирует его. Таким образом, пользователь копирует большую папку (внутри многих файлов), запускается процесс копирования операционной системы, занимает 5 минут, но в то же время мое приложение получает уведомление об изменении файла. Это проблема, потому что, когда я получаю уведомление об изменении, мое приложение запускает некоторые операции над этими файлами, но копия уже выполняется !!!! – paganotti

0

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

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

2

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

Таким образом, вы можете игнорировать новые файлы, которые заканчиваются .tmp, а переименование - это атомная операция.

Если вы не можете изменить процесс копирования, все, что вы можете сделать, это добавить таймер, чтобы подождать, скажем, полчаса, чтобы убедиться, что копия действительно закончена.

Более мелкозернистый (и более рискованный) подход заключается в том, чтобы добавить цикл, который проверяет размер файла и останавливается, когда размер файла не изменяется в течение определенного времени, но это также сложно сделать правильно.

Хуже того, это не мешает вам просматривать частичные файлы (когда процесс копирования был завершен посередине).