Windows共享只读文件被Python脚本读取时阻塞本地写入问题排查
解决SMB共享远程读取XML导致本地计分板程序写入阻塞的问题
核心问题分析
你遇到的是Windows SMB共享下的文件锁定冲突:即使是远程只读读取,默认的文件打开模式会请求不允许写入的共享锁,导致本地计分板程序无法获取写入权限,进而停止更新文件。本地读取无问题、远程读取才触发,正是SMB协议在处理跨进程跨机器文件访问时的锁机制导致的。
另外,你代码里的SB_File.close()是多余的——with open(...)会在代码块结束后自动关闭文件,手动调用反而可能引发不必要的资源问题。
具体解决方案
1. 修改文件打开模式,允许共享写入
在Windows下,Python的默认open()函数会默认设置FILE_SHARE_READ,阻止其他进程写入。你需要通过os.open()指定共享标志,允许本地程序继续写入文件:
import os import xml.etree.ElementTree as ET try: if includes.OkToReadSBFile: # 打开文件时明确允许本地进程写入、删除该文件 fd = os.open(SBSourceFile, os.O_RDONLY | os.O_SHARE_DELETE | os.O_SHARE_WRITE) # 通过文件描述符创建文件对象,用with自动管理关闭 with os.fdopen(fd, 'r', encoding='utf-8') as sb_file: xml_content = sb_file.read() # 用fromstring解析内存中的内容,避免直接操作文件对象可能的锁残留 mytree = ET.fromstring(xml_content) includes.LastMyTree = mytree except Exception as e: # 保留你原来的异常处理逻辑 pass
2. 关闭共享文件夹的离线缓存
在计分板PC上操作:
- 找到共享的文件夹,右键选择「属性」
- 切换到「共享」标签页,点击「高级共享」
- 点击「缓存」,选择「无」,关闭离线文件缓存
- 确认设置后重启共享服务(或直接重启PC)
关闭缓存可以减少SMB协议对文件的锁定和缓存延迟,降低冲突概率。
3. 优化读取逻辑,减少不必要的文件访问
记录上次读取的文件修改时间,只有当文件确实更新时才读取,减少锁冲突的机会:
# 先在全局或includes中初始化LastModifyTime if not hasattr(includes, 'LastModifyTime'): includes.LastModifyTime = 0 try: if includes.OkToReadSBFile: current_mtime = os.path.getmtime(SBSourceFile) if current_mtime != includes.LastModifyTime: # 执行上面的文件读取逻辑 includes.LastModifyTime = current_mtime except Exception as e: pass
4. 脱离PyCharm环境运行测试
PyCharm的调试模式会启用文件监控和额外的资源占用,可能放大锁冲突问题。直接运行Python脚本或打包成exe,观察问题是否缓解。
补充说明
- 你提到的读取间隔只是影响冲突概率,无法解决根本问题——核心还是文件共享的锁机制。
- 即使做了以上调整,偶尔的读取失败仍可能发生,保持你的try/except逻辑即可。
内容的提问来源于stack exchange,提问作者Bleve
相关产品推荐
相关产品推荐

