2014-10-29 95 views
0

外部二進制輸出從我的Python腳本我需要調用因此兩個外部二進制文件,以處理文件中的兩個步驟:處理文件輸入/從蟒蛇

import os, subprocess 
sbp = subprocess.Popen(['program_1', '-i', 'input.file', '-o', 'temp.file']) 
sbp = subprocess.Popen(['program_2', '-i', 'temp.file', '-o', 'output.file'])      
os.remove('temp.file') 

不過,這將是不錯的速度 - 通過使用基於虛擬RAM的文件而不是基於「物理」磁盤的管道來減少磁盤使用量。我知道我可以使用StringIOtempfile.SpooledTemporaryFile()來處理Python腳本中的虛擬文件,但有沒有可能將鏈接傳遞給這樣的文件到外部二進制文件?

回答

0
from subprocess import Popen 
from tempfile import NamedTemporaryFile 

tmp = NamedTemporaryFile('w+') 
sbp = Popen(['program_1', '-i', 'input.file', '-o', tmp.name]) 
sbp = Popen(['program_2', '-i', tmp.name, '-o', 'output.file'])      
tmp.close() 

最後tmp將被刪除。

+0

它也沒有找到臨時文件到RAM – Roman 2014-10-29 13:38:11

+0

您正在尋找的是[mmap](https://docs.python.org/2/library/mmap.html)模塊 – 2014-10-29 16:02:18

+0

當您調用外部二進制,它不能與標準輸入/標準輸出一起使用,你必須提供包含'-i'/' - o'鍵的文件路徑的字符串變量。在tempfile模塊中有一個特殊的屬性'name'。但是,mmap似乎沒有模擬。可能,這根本不可能。 – Roman 2014-10-29 16:28:01

1

假設你可以告訴你2個程序讀取,並從標準輸入和stdout寫入/,你可以管從一個子命令其他:

import os, subprocess 
sp1 = subprocess.Popen(['program_1', '-i', 'input.file'], stdout=subprocess.PIPE) 
sp2 = subprocess.Popen(['program_2', '-o', 'output.file'], stdin=sp1.stdout) 
sp1.stdout.close() 
sp2.communicate() 

https://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline

另一個選項(UNIX)是使用命名管道(在操作系統級別創建的,例如mkfifo /tmp/mypipe):

import os, subprocess 
os.mkfifo('/tmp/mypipe') 
sp1 = subprocess.Popen(['program_1', '-i', 'input.file', '-o', '/tmp/mypipe']) 
sp2 = subprocess.Popen(['program_2', '-i', '/tmp/mypipe', '-o', 'output.file']) 

而且它也應該可以使用os.pipe()

+0

這就是程序無法讀寫標準輸入/輸出的問題。第二個選項似乎也使用HDD,所以它只是一種將臨時文件放在另一個地方的方法,而不是繞過它的創建。 – Roman 2014-10-29 13:35:23

+0

命名管道/ fifo並不是真正的文件,因爲它不會將用戶數據寫入磁盤。至少在Linux中,內核將在讀寫過程之間轉發數據而不寫入文件系統。另外,在適當的情況下,讀寫過程將在IO上阻塞。除非讀者已經在非阻塞模式下打開管道,否則讀取器將會阻塞,如果沒有什麼可讀的話。鑑於目標程序與stdin/stdout的不靈活性,命名管道可能是最好的解決方案。 – mhawke 2014-10-30 10:47:28

+0

是否有可能同時使用多個管道?我的腳本是多線程的,所以我用這種語法等待線程之間的衝突。 – Roman 2014-10-30 12:42:25