2010-11-30 132 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执行设置管道的肮脏工作。

相关问题