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

Python调用外部可执行文件时如何实时将控制台输出写入文件

问题根因

你当前的脚本只能在程序退出后写入文件,核心原因是:绝大多数C/C++编写的控制台程序(包括Rogue这类经典ASCII游戏)的标准输出默认采用缓冲策略:当输出目标是终端时启用行缓冲,遇到换行符就刷新缓冲区;当输出目标是管道/文件时启用全缓冲,只有缓冲区填满或者程序退出时才会真正写入数据。

可行解决方案

方案1:实时逐行写入(最常用)

该方案通过行缓冲读取子进程输出,每拿到一行就写入文件,延迟最低:

import subprocess
import sys

def main():
    # buffering=1开启行缓冲,写入内容即时落盘
    with open('output.txt', 'w', encoding='utf-8', buffering=1) as out_file:
        proc = subprocess.Popen(
            "ROGUE.EXE",
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT, # 合并错误输出,避免内容遗漏
            text=True,
            universal_newlines=True
        )
        # 持续读取子进程输出,直到进程退出
        for line in iter(proc.stdout.readline, ''):
            # 可选:同步打印到控制台,方便实时查看游戏内容
            sys.stdout.write(line)
            sys.stdout.flush()
            out_file.write(line)
        proc.wait()

if __name__ == "__main__":
    main()

如果该方案仍然没有实时写入,说明子进程的全缓冲机制没有被打破,可以用伪终端工具包装程序启动:Windows平台可以用winpty,将启动参数改为["winpty.exe", "ROGUE.EXE"]即可,让子进程误以为自己输出到终端,自动启用行缓冲。

方案2:按固定间隔批量写入

如果你需要按固定时间间隔增量写入,可以按固定字节读取、定时刷新:

import subprocess
import time

# 每次读取的字节数,可根据需求调整
READ_CHUNK = 1024
# 写入间隔,单位秒
WRITE_INTERVAL = 1

with open('output.txt', 'wb') as out_file, \
     subprocess.Popen("ROGUE.EXE", stdout=subprocess.PIPE) as proc:
    while True:
        chunk = proc.stdout.read(READ_CHUNK)
        # 进程退出后会返回空字节,结束循环
        if not chunk:
            break
        out_file.write(chunk)
        # 强制刷新缓冲区到磁盘
        out_file.flush()
        # 等待固定间隔后再读下一批
        time.sleep(WRITE_INTERVAL)
    proc.wait()
注意事项
  • 如果你不需要保留控制台输出的颜色、控制字符等特殊内容,可以在写入文件前过滤掉不可见字符,避免输出文件出现乱码。
  • Rogue这类老DOS游戏的输出编码通常是CP437,如果遇到解码报错,可以去掉text=True参数改为二进制读写,不需要解码直接写入文件即可避免编码问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:27:02