2016-12-01 68 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)'(不確定,模塊非常複雜)。我很高興挖出了一個解決方案。我不得不打開很久以前爲此開發的一個低級模塊(我的需求是不斷將「是」連續傳遞給進程) –

相關問題