Qt или PyQt - проверять, когда файл используется другим процессом.Дождитесь окончания копирования - PullRequest
0 голосов
/ 13 марта 2012

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

Я работаю над Mac OS X.

спасибо

Обновление

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

Ответы [ 4 ]

2 голосов
/ 15 марта 2012

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

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

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

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

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

0 голосов
/ 15 марта 2012

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

Вот простой пример класса 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 голосов
/ 15 марта 2012

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

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

0 голосов
/ 13 марта 2012

Попробуйте использовать QtConcurrent framework. В частности, проверьте 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);
...