简短版本(如果你可以回答短版本它为我做的工作,其余的主要是为了其他有类似任务的人的利益):
在Windows的python中,我想创建2个文件对象,附加到同一个文件(它不必是硬盘上的实际文件),一个用于读取,一个用于写入,这样如果读取结束试图读取它永远不会得到EOF(它会阻止直到写入内容).我认为在linux中os.mkfifo()可以完成这项工作,但在Windows中它并不存在.可以做些什么? (我必须使用文件对象).
一些额外的细节:
我有一个python模块(不是我写的)通过stdin和stdout(使用raw_input()和print)播放某个游戏.我也有一个Windows可执行文件,通过stdin和stdout播放相同的游戏.我想让他们一对一玩,并记录他们所有的沟通.
这是我可以编写的代码(get_fifo()函数没有实现,因为这是我不知道做的Windows):
- class Pusher(Thread):
- def __init__(self,source,dest,p1,name):
- Thread.__init__(self)
- self.source = source
- self.dest = dest
- self.name = name
- self.p1 = p1
- def run(self):
- while (self.p1.poll()==None) and\
- (not self.source.closed) and (not self.source.closed):
- line = self.source.readline()
- logging.info('%s: %s' % (self.name,line[:-1]))
- self.dest.write(line)
- self.dest.flush()
- exe_to_pythonmodule_reader,exe_to_pythonmodule_writer =\
- get_fifo()
- pythonmodule_to_exe_reader,pythonmodule_to_exe_writer =\
- get_fifo()
- p1 = subprocess.Popen(exe,shell=False,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
- old_stdin = sys.stdin
- old_stdout = sys.stdout
- sys.stdin = exe_to_pythonmodule_reader
- sys.stdout = pythonmodule_to_exe_writer
- push1 = Pusher(p1.stdout,exe_to_pythonmodule_writer,'1')
- push2 = Pusher(pythonmodule_to_exe_reader,p1.stdin,'2')
- push1.start()
- push2.start()
- ret = pythonmodule.play()
- sys.stdin = old_stdin
- sys.stdout = old_stdout
按照上面的两个答案,我不小心碰到了答案. os.pipe()完成了这项工作.谢谢您的回答.
我发布了完整的代码以防其他人正在寻找这个:
- import subprocess
- from threading import Thread
- import time
- import sys
- import logging
- import tempfile
- import os
- import game_playing_module
- class Pusher(Thread):
- def __init__(self,proc,name):
- Thread.__init__(self)
- self.source = source
- self.dest = dest
- self.name = name
- self.proc = proc
- def run(self):
- while (self.proc.poll()==None) and\
- (not self.source.closed) and (not self.source.closed):
- line = self.source.readline()
- logging.info('%s: %s' % (self.name,line[:-1]))
- self.dest.write(line)
- self.dest.flush()
- def get_reader_writer():
- fd_read,fd_write = os.pipe()
- return os.fdopen(fd_read,'r'),os.fdopen(fd_write,'w')
- def connect(exe):
- logging.basicConfig(level=logging.DEBUG,\
- format='%(message)s',\
- filename=LOG_FILE_NAME,filemode='w')
- program_to_grader_reader,program_to_grader_writer =\
- get_reader_writer()
- grader_to_program_reader,grader_to_program_writer =\
- get_reader_writer()
- p1 = subprocess.Popen(exe,stdout=subprocess.PIPE)
- old_stdin = sys.stdin
- old_stdout = sys.stdout
- sys.stdin = program_to_grader_reader
- sys.stdout = grader_to_program_writer
- push1 = Pusher(p1.stdout,program_to_grader_writer,'1')
- push2 = Pusher(grader_to_program_reader,'2')
- push1.start()
- push2.start()
- game_playing_module.play()
- sys.stdin = old_stdin
- sys.stdout = old_stdout
- fil = file(LOG_FILE,'r')
- data = fil.read()
- fil.close()
- return data
- if __name__=='__main__':
- if len(sys.argv) != 2:
- print 'Usage: connect.py exe'
- print sys.argv
- exit()
- print sys.argv
- print connect(sys.argv[1])