pyqt实现对文件创建/删除/修改的监控

方法摘要:监控文件状态是否发生变化(创建/删除/修改),如发生变化释放Signal

实现思路:创建一个signal;创建一个列表,里面包含一个或多个文件路径;并启动一个timer,将timeout关联到一个slot,在slot中顺序检查列表中的这些文件是否发生了改变(创建/删除/修改),如果发生变化,则emit signal、并停止此次检查(所以fileChanged信号是关于列表中第一个发生变化的路径的。

如何使用:①利用addPath添加要监控的路径,②将你的slot与fileChanged信号connect,③signal提供两个信息:发生改变的路径,和改变的类型、时间

一些说明:

  1. 为什么不用QFileSystemWatcher:①如果在监视开始之前文件不存在,那么后来文件创建之后也不能对其进行监视(个人猜测是因为由于不存在直接不能添加到监视列表);②如果文件中途被删掉了,那么即便再创建了也没法继续监视了
  2. 目前python水平较low,所以上面所说的“列表”用了比较low的实现方式:一个数组是文件名、一个数组是文件是否存在的标志、另加一个计数。
  3. win10测试,测试了对文件的监控,但是没有测试对文件夹的监控;
  4. 可能的bug:测试程序偶有出现卡死的现象,尚不知为何。
  5. fileChanged信号检测到第一个改变的path之后就发出了,后面再有修改并不做监测。
  6. 适用常见情况:修改、创建、删除、删除了又重新创建了
  7. 必要的改进:addPath中检查是否已经存在于列表中、避免重复添加

附1/2:MyWatcher.py

import os, sys, time
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

def timestr(t):
    return time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(t))

class MyFileSystemWatcher(QObject):
    fileChanged = pyqtSignal(str, str) # path, information 

    def __init__(self):
        super().__init__()
        self.pathList = ['NULL']
        self.pathFlag = [0]
        self.pathNum = 1
        self.timer = QTimer()
        self.timerInterval = 0.1 # regard it as a delay, 0.1 means 100ms
        self.timer.start(self.timerInterval*1000)
        self.timer.timeout.connect(self.slot_timeout_checkChange)

    def addPath(self,path):
        self.pathList.append(path)
        self.pathNum = self.pathNum + 1
        if os.path.exists(path):
            self.pathFlag.append(1)
        else:
            self.pathFlag.append(0)

    def slot_timeout_checkChange(self):
        for i in range(self.pathNum):
            path = self.pathList[i]
            timeCurrent = time.time()
            if self.pathFlag[i]: # exits before this check (may or may not exist now!)
                if os.path.exists(path): # still exists but has been modified (do nothing if still exists unmodified)
                    timeModify = os.stat(path).st_mtime; # not self.pathModifiedTime[i] since modification may not be detected last time
                    if timeCurrent - timeModify < self.timerInterval :
                        self.fileChanged.emit( path, 'modified at '+timestr(timeModify) )
                        break 
                else: # no more exist, so it was deleted at timeCurrent-timerInterval or later. Since timerInterval<=1 & the samllest time unit is second, it can be regraded that it is deleted now
                    self.fileChanged.emit(path,'removed at ' + timestr(timeCurrent) )
                    self.pathFlag[i] = 0
                    break 
            else: # does not exist before this check (may or may not exist now!)
                if os.path.exists(path): # now exists, so it is just created
                    timeModify = os.stat(path).st_mtime;
                    self.fileChanged.emit(path, 'created at ' + timestr(timeModify) )
                    self.pathFlag[i] = 1
                    break

附2/2:测试

import os, sys, time
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from MyWatcher import *

ftxt = 'test_file.txt'

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.filewatcher = MyFileSystemWatcher()
        self.filewatcher.addPath(ftxt)
        self.label = QLabel('Content of {0}:'.format(ftxt))
        self.textedit = QTextEdit()
        self.slot_load_show_text() #init
        self.filewatcher.fileChanged.connect(self.slot_fileChanged_update)
        layout_vbox = QVBoxLayout()
        layout_vbox.addWidget(self.label)
        layout_vbox.addWidget(self.textedit)
        self.setLayout(layout_vbox)
        self.setWindowTitle('Mainwindow')
        self.setGeometry(300,300,500,200)
        self.show()

    def slot_load_show_text(self):
        if os.path.exists(ftxt):
            time_modified = os.stat(ftxt).st_mtime
            time_modified_str=time.strftime( '%Y-%m-%d %H:%M:%S',time.localtime(time_modified) )
            self.textedit.setText(open(ftxt,'r').read())
            self.textedit.append('*** last modified at {0} ***'.format(time_modified_str) )
        else:
            self.textedit.setText('** {0} does not exist **'.format(ftxt))

    def slot_fileChanged_update(self,pathModified,infoModify):
        self.slot_load_show_text()
        print(pathModified, infoModify)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainwindow = MainWindow()
    sys.exit(app.exec_())

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值