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

使用with语句后无法删除文件,疑子进程占用文件资源

问题描述

我用Python开发自动评分程序,需要将学生Java作业的程序输出写入临时txt文件。通过with语句成功写入文件后,执行os.remove(file.txt)删除文件时,持续出现以下错误:

PermissionError: [WinError 32] 该文件正被另一进程占用,无法访问: 'file.txt'

我猜测是with语句未正确关闭文件,尝试添加file.close()但无作用(我知道这有些多余)。也怀疑问题出在subprocess.Popen()语句,但之前在其他程序中使用该语句操作同一文件时并未出现问题。尝试用kill()终止子进程,但未能成功实现。

相关代码如下:

hw_file = f"{submissions_folder}\\TaylorDavisOnTime.java" # example of naming style for student assignments
student_txt_file =  hw_file.replace(f"{submissions_folder}\\", f"{submissions_folder}\\output\\").replace(".java", "Output.txt")

with open(student_txt_file, "w") as file:
    output = subprocess.Popen(["java", hw_file], stdin=subprocess.PIPE, stdout=file, text=True)
    for input in input_values:
        output.stdin.write(input[0])
        output.stdin.write(str(input[1]))
        output.stdin.write(str(input[2]))  
    output.stdin.flush()
    output.stdin.close() 
    # output.kill() # still playing with this
    remove = True 
    file.close() # redundant, but does nothing

if remove: 
    os.remove(student_txt_file)
问题分析与解决方向
  • 核心原因:你启动的Java子进程仍在运行,它的标准输出流还占用着目标txt文件,导致Python进程无法删除该文件。with语句确实已关闭file句柄,但子进程未结束时,操作系统会判定文件处于占用状态。
  • 具体解决步骤:
    1. 等待子进程完全退出:在关闭标准输入后,调用output.wait()等待Java程序执行完毕并退出,确保它释放对输出文件的占用。这是解决文件占用问题的关键。
    2. 修正输入传递格式:当前的输入写法可能不符合Java程序的预期(比如缺少换行符),导致Java程序一直等待输入,无法正常结束。要根据Java程序的输入要求调整,例如每个输入项后添加\n,确保程序能接收完所有输入并执行完成。
    3. 移除冗余的文件关闭操作:with语句会自动管理文件生命周期,手动调用file.close()完全没必要,应删除该代码。
    4. 可选优化:避免临时文件:如果评分逻辑不需要持久化输出文件,可直接通过subprocess.communicate()获取Java程序的输出内容,无需写入文件,从根源上避免文件占用问题。

修改后的示例代码:

hw_file = f"{submissions_folder}\\TaylorDavisOnTime.java"
student_txt_file =  hw_file.replace(f"{submissions_folder}\\", f"{submissions_folder}\\output\\").replace(".java", "Output.txt")

with open(student_txt_file, "w") as file:
    output = subprocess.Popen(["java", hw_file], stdin=subprocess.PIPE, stdout=file, text=True)
    # 按Java程序预期格式传递输入,添加换行符
    for input in input_values:
        output.stdin.write(f"{input[0]}\n{str(input[1])}\n{str(input[2])}\n")
    output.stdin.flush()
    output.stdin.close()
    # 等待子进程执行完毕
    output.wait()
    remove = True

if remove: 
    os.remove(student_txt_file)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 16:57:07