2016-12-01 65 views
2

我需要只发送文件的一部分到另一个进程的STDIN?我可以重写io.BufferedReader中的默认read()方法吗?

#Python 3.5 
from subprocess import PIPE, Popen, STDOUT 

fh = io.open("test0.dat", "rb") 
fh.seek(10000) 
p = Popen(command, stdin=fh, stdout=PIPE, stderr=STDOUT) 
p.wait() 

我确保command将只读取从标准输入1000多个字节,然后遇到EOF怎么办。 我无法控制命令如何读取标准输入。

+0

我的回答是错误的。问题是'Popen'使用真正的操作系统句柄,所以不可能像这样愚弄它。 –

回答

3

问题是,当传递一个句柄时,Popen试图获得fileno,并使用真正的操作系统句柄,所以不可能用其他类似文件的对象轻松地把它弄糊涂。

但是你可以设置PopenstdinPIPE,只写了正确的字节数到它,可能在一小块一小块的,在你选择的节奏,并关闭它之后

import io 
from subprocess import PIPE, Popen, STDOUT 

fh = io.open("test0.dat", "rb") 
fh.seek(10000) 


p = Popen(command, stdin=PIPE, stdout=PIPE, stderr=STDOUT) 
p.stdin.write(fh.read(1000)) 
# do something & write again 
p.stdin.write(fh.read(1000)) 
# now it's enough: close the input 
p.stdin.close() 

p.wait() 

不过要小心:因为stdinstdout使用PIPE,则必须消耗stdout以避免死锁。

+0

编辑我的答案。你可以阅读小块。与大文件的区别在于您可以决定何时关闭管道。 –

+0

太棒了,谢谢!你知道在fileno()之后Popen调用哪个方法吗?我想到了重写,但没有像read/readline/readline似乎被调用。 – olekb

+0

我认为在得到文件描述符后,最终使用了'os.read()':extract:'data = os.read(fd,4096)'(不确定,模块非常复杂)。我很高兴挖出了一个解决方案。我不得不打开很久以前为此开发的一个低级模块(我的需求是不断将“是”连续传递给进程) –

相关问题