You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Watchdog监听TDMS文件后打开报PermissionError权限错误如何解决

错误根因

该PermissionError并非Python脚本没有文件访问权限,而是文件被写入程序独占锁定:watchdog的on_created事件会在文件系统创建文件条目时立刻触发,此时生成TDMS文件的程序还未完成写入、仍持有文件的独占锁,直接打开就会触发权限报错。手动传入路径可以正常读取,是因为操作时文件已经写完、锁已经被释放。

修复方案

在触发on_created事件后增加文件就绪校验逻辑,确认文件写入完成、无锁定后再执行读取,修改后的完整代码如下:

import os
import nptdms
import numpy
import watchdog.events
import watchdog.observers
import time

def wait_file_ready(file_path, timeout=30, check_interval=0.5):
    """等待文件写入完成且无其他程序占用
    timeout: 最大等待时长,单位秒
    check_interval: 锁定检查间隔,单位秒
    """
    start_time = time.time()
    while time.time() - start_time < timeout:
        try:
            # 尝试打开文件确认无锁定
            with open(file_path, 'rb') as f:
                # 校验文件大小1秒内无变化,避免半写入状态
                size_before = os.path.getsize(file_path)
                time.sleep(1)
                size_after = os.path.getsize(file_path)
                if size_before == size_after:
                    return True
        except PermissionError:
            time.sleep(check_interval)
    print(f"文件 {file_path} 等待就绪超时,跳过读取")
    return False

class Handler(watchdog.events.PatternMatchingEventHandler):
    def __init__(self):
        # Set the patterns for PatternMatchingEventHandler
        watchdog.events.PatternMatchingEventHandler.__init__(self, patterns=['*.tdms'],
                                                         ignore_directories=False, case_sensitive=False)

    def on_created(self, event):
        print("Event created - % s." % event.src_path)
        # 新增文件就绪校验后再读取
        if wait_file_ready(event.src_path):
            GET_DATA(event.src_path)

def GET_DATA(filename):
    print("DATA FUNC:",filename)
    tdms_file = nptdms.TdmsFile.open(filename)
    group = tdms_file["Ramp 15"]
    channel = group["TorqueTransducer"]
    data = channel[:]
    print(group)
    print(channel)
    print(numpy.max(data))

if __name__ == "__main__":
    src_path = r"C:\PythonTargetDirectory"
    event_handler = Handler()
    observer = watchdog.observers.Observer()
    observer.schedule(event_handler, path=src_path, recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(60)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()
else:
    while True:
        time.sleep(60)
可选调整项
  • 如果TDMS文件本身很大,可以根据实际写入速度调整timeout和check_interval参数
  • 不需要严格校验写入完成的场景可以删掉文件大小对比逻辑,仅校验文件可打开即可

内容的提问来源于stack exchange,提问作者AndyPD74

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 04:45:04