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
相关产品推荐
相关产品推荐

