Qt或PyQt-检查文件是否被其他进程使用。等到完成拷贝

Qt或PyQt-检查文件是否被其他进程使用。等到完成拷贝,qt,copy,pyqt4,monitor,Qt,Copy,Pyqt4,Monitor,早上好, 当大文件或大目录完成复制时,检查的最佳策略是什么? 我想等到文件完全完成后再复制。q中有代码示例吗 我正在开发MacOSX 谢谢 更新 我使用QFileSystemWatcher。问题是,当o copy正在进行时,我会收到文件或目录更改通知。所以用户复制一个大文件夹(里面有很多文件),操作系统复制过程开始,需要5分钟,但同时我的应用程序会收到文件更改通知。这是一个问题,因为当我收到更改通知时,我的应用程序开始对该文件执行某些操作,但复制已在进行中 尝试使用框架。 特别是,请查看QFut

早上好, 当大文件或大目录完成复制时,检查的最佳策略是什么? 我想等到文件完全完成后再复制。q中有代码示例吗

我正在开发MacOSX

谢谢

更新


我使用QFileSystemWatcher。问题是,当o copy正在进行时,我会收到文件或目录更改通知。所以用户复制一个大文件夹(里面有很多文件),操作系统复制过程开始,需要5分钟,但同时我的应用程序会收到文件更改通知。这是一个问题,因为当我收到更改通知时,我的应用程序开始对该文件执行某些操作,但复制已在进行中

尝试使用框架。 特别是,请查看QFuture和。您可以在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);
boolcopyfunction(){
//在此处复制操作,成功时返回true
}
MyHandlerClass myObject;
未来观察者;
连接(&watcher,信号(finished()),&myObject,插槽(handleFinished());
QFuture future=QtConcurrent::run(copyFunction);

我认为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!

由于您无法控制外部应用程序,因此我建议您在处理文件时锁定这些文件。这样,其他程序在锁定时将无法访问它们


或者,如果您可以访问另一个程序的源代码,您应该通过套接字、消息或您喜欢的任何方法实现某种形式的进程间通信。

只有一种可靠的方法可以做到这一点:将复制过程改为写入临时文件,然后在复制完成后重命名它们

这样,您就可以忽略以
.tmp
结尾的新文件,而重命名是一个原子操作

如果您无法更改复制过程,您所能做的就是添加一个计时器等待,例如,半小时,以确保复制真正完成

一种更细粒度(且风险更大)的方法是添加一个循环,用于检查文件大小,并在文件大小在一定时间内没有更改时停止,但这也很难正确执行


更糟糕的是,这并不能阻止您读取部分文件(当复制过程中途终止时)。

问题在于复制文件的不是我的应用程序,而是外部应用程序。因此,我的应用程序必须等待外部应用程序完成复制到我的应用程序正在监视的目录以捕获更改文件或目录。在这种情况下,您可以使用QFileSystemWatcher:仔细阅读平台特定问题的说明我使用QFileSystemWatcher。问题是,当o copy正在进行时,我会收到文件或目录更改通知。所以用户复制一个大文件夹(里面有很多文件),操作系统复制过程开始,需要5分钟,但同时我的应用程序会收到文件更改通知。这是一个问题,因为当我收到更改通知时,我的应用程序开始对该文件执行某些操作,但复制已在进行中!!!!好了,现在清楚了。如果您对复制文件的过程没有任何控制权,恐怕唯一的方法就是使用lsof之类的工具监视目标目录,以确切了解发生了什么。或者,如果您确切知道复制发生的时间,您可以假设当您的观察者停止发出信号时复制完成,但我担心此解决方案可能非常不可靠。仅供参考:我最近了解到,如果服务器运行windows,QFileSystemWatcher(在windows上运行)也可以在网络共享上工作。对于在旧samba版本的linux服务器上运行的网络共享,它不能正常工作——如果它在最新的samba版本上正常工作,则不知道。