2010-11-30 35 views
1

我有大約500,000 + txt文件的總數約7 +演出。我正在使用python把它們放入一個sqlite數據庫。我正在創建2個表,1.是pK和文件的超鏈接。 對於另一個表,我使用的是一個實體提取器,它是由一個同事在perl中開發的。Python子流程;無法讀取標準輸出

爲了達到這個目的,我使用了subprocess.Popen()。 T在此方法之前,我在循環的每次迭代中都打開了perl,但僅僅爲了便於使用而花費很高。

我需要perl是動態的,我需要能夠從它發回數據和第四個數據,並且該過程不會終止,直到我告訴它這樣做。 perl被修改了,所以perl接受一個文件的完整字符串作爲stdin,並且當它得到\ n時給了我一個stdout。但我在讀取數據時遇到了問題...

如果我使用通信,在我的循環的下一次迭代中,我的子進程終止,出現I/O錯誤。如果我嘗試使用readline()或read(),它會鎖定。以下是我正在嘗試的不同行爲的一些示例。

這使我的系統死鎖,我需要強制關閉python才能繼續。

numberExtractor = subprocess.Popen(["C:\\Perl\\bin\\perl5.10.0.exe","D:\\MyDataExtractor\\extractSerialNumbers.pl"], stdout=subprocess.PIPE, stdin= subprocess.PIPE) 
for infile in glob.glob(self.dirfilename + '\\*\\*.txt'): 
    f = open(infile) 
    reportString = f.read() 
    f.close() 

    reportString = reportString.replace('\n',' ') 
    reportString = reportString.replace('\r',' ') 
    reportString = reportString +'\n' 

    numberExtractor.stdin.write(reportString) 
    x = numberExtractor.stdout.read()  #I can not see the STDOUT, python freezes and does not run past here. 

    print x 

這取消了子進程,我在我的循環的下一次迭代中得到一個I/O錯誤。

numberExtractor = subprocess.Popen(["C:\\Perl\\bin\\perl5.10.0.exe","D:\\MyDataExtractor\\extractSerialNumbers.pl"], stdout=subprocess.PIPE, stdin= subprocess.PIPE) 
for infile in glob.glob(self.dirfilename + '\\*\\*.txt'): 

    f = open(infile) 
    reportString = f.read() 
    f.close() 

    reportString = reportString.replace('\n',' ') 
    reportString = reportString.replace('\r',' ') 
    reportString = reportString +'\n' 
    numberExtractor.stdin.write(reportString) 
    x = numberExtractor.communicate() #Works good, I can see my STDOUT from perl but the process terminates and will not run on the next iteration 

    print x 

如果我只是像這樣運行,它會運行所有的代碼。對於我的文件夾中的每個項目,打印行都是',mode'rb'at 0x015dbf08>。

numberExtractor = subprocess.Popen(["C:\\Perl\\bin\\perl5.10.0.exe","D:\\MyDataExtractor\\extractSerialNumbers.pl"], stdout=subprocess.PIPE, stdin= subprocess.PIPE) 
for infile in glob.glob(self.dirfilename + '\\*\\*.txt'): 
    f = open(infile) 
    reportString = f.read() 
    f.close() 

    reportString = reportString.replace('\n',' ') 
    reportString = reportString.replace('\r',' ') 
    reportString = reportString +'\n' 

    numberExtractor.stdin.write(reportString) 
    x = numberExtractor.stdout    #I can not get the value of the object, but it runs through all my files fine. 

    print x 

希望我做一個簡單的錯誤,但有一些方法我可以將文件發送到我的perll(標準輸入),得到了標準輸出,然後無需重新打開我的子過程中的每個文件重複我的循環?

+0

Perl程序是否可以輕鬆轉換爲Python?這個程序可以很容易地轉換成Perl嗎?較低的複雜性將有助於此。 – nmichaels 2010-11-30 17:57:13

+0

在這種情況下,這不是一個真正的選擇,那是我甚至在我開始走這條路之前的第一個想法。 – dfarni 2010-11-30 18:13:30

回答

2

考慮使用shell。生活更簡單。

perl extractSerialNumbers.pl *.txt | python load_database.py 

不要因爲讓Python啓動perl以及所有這些而煩惱。只需從perl中讀取結果並在Python中處理這些結果即可。

由於兩個進程併發運行,這往往是相當快的,並且使用大量的CPU資源,而不需要太多編程。

在Python程序(load_database.py)中,您可以簡單地使用fileinput模塊讀取stdin上提供的整個文件。

import fileinput 
for line in fileinput.input(): 
    load the row into the database 

這就是關於Python程序中所有需要的東西,如果你讓shell執行設置管道的骯髒工作。

相關問題