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

Windows下使用tempfile复制文件遇Errno 13权限拒绝问题求助

解决Windows下临时文件复制权限拒绝问题

这个问题我太熟了——完全是Windows和Linux文件系统锁机制的差异搞的鬼!你猜的方向没错,核心矛盾就是Windows的文件锁定规则和NamedTemporaryFile默认行为的冲突。

问题根源

在Windows中,当一个文件处于打开的写入状态时,系统会强制锁定它,阻止任何其他操作(哪怕是同一个进程里的复制)访问该文件;而Linux允许这种跨操作的文件访问。同时NamedTemporaryFile默认的delete=True参数会让文件在关闭时自动删除,这就陷入了「不关闭无法复制,关闭了文件就没了」的死循环。

解决方案:设置delete=False并手动清理临时文件

我们只需要给NamedTemporaryFile加上delete=False参数,让临时文件关闭后不会被自动删除,等完成复制操作后再手动删除它。下面是修正后的完整代码:

from pathlib import Path
from shutil import copyfile
from tempfile import NamedTemporaryFile
import os

sourcefile = Path("Path\\to\\source").resolve()
insert_lineno = 2
insert_data = "# Mean magnitude = " + str(mean_mag)+"\n"

# 关键改动1:添加delete=False,同时指定encoding避免跨系统乱码
with sourcefile.open(mode="r", encoding="utf-8") as source:
    destination = NamedTemporaryFile(mode="w", dir=str(sourcefile.parent), delete=False, encoding="utf-8")
    lineno = 1
    while lineno < insert_lineno:
        line = source.readline()
        destination.write(line)
        lineno += 1
    destination.write(insert_data)
    # 按块写入剩余内容,保持原代码的性能优势
    while True:
        data = source.read(1024)
        if not data:
            break
        destination.write(data)
    destination.flush()
    # 关键改动2:先关闭临时文件,解除Windows的文件锁定
    destination.close()
    
    # 现在可以安全执行复制了
    copyfile(destination.name, str(sourcefile))
    
    # 关键改动3:手动删除临时文件,避免残留垃圾
    os.unlink(destination.name)

额外优化:添加异常处理确保临时文件被清理

为了避免复制过程中出错导致临时文件残留,建议加上try...finally块,确保无论操作成功还是失败,临时文件都会被删除:

from pathlib import Path
from shutil import copyfile
from tempfile import NamedTemporaryFile
import os

sourcefile = Path("Path\\to\\source").resolve()
insert_lineno = 2
insert_data = "# Mean magnitude = " + str(mean_mag)+"\n"
temp_file_path = None

try:
    with sourcefile.open(mode="r", encoding="utf-8") as source:
        destination = NamedTemporaryFile(mode="w", dir=str(sourcefile.parent), delete=False, encoding="utf-8")
        temp_file_path = destination.name
        lineno = 1
        while lineno < insert_lineno:
            line = source.readline()
            destination.write(line)
            lineno += 1
        destination.write(insert_data)
        while True:
            data = source.read(1024)
            if not data:
                break
            destination.write(data)
        destination.flush()
        destination.close()
        
        copyfile(temp_file_path, str(sourcefile))
finally:
    # 无论成功失败,都清理临时文件
    if temp_file_path and os.path.exists(temp_file_path):
        os.unlink(temp_file_path)

这样既解决了Windows的权限问题,又保留了批量处理文件的性能优势——不用频繁打开关闭原文件,通过临时文件一次性处理后覆盖即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:42:45