我正在使用线程从标准输出编写非块读取文件的代码。我使用在线示例开始。启动子进程时会创建该文件。但是,在ResultEvent中读取文件后,文件将被清除。我无法调试线程,也不确定那里发生了什么。有谁给我一个线索?这是代码:
EVT_RESULT_ID = wx.NewId()
def EVT_RESULT(win, func):
win.Connect(-1, -1, EVT_RESULT_ID, func)
class ResultEvent(wx.PyEvent):
def __init__(self, data,file):
wx.PyEvent.__init__(self)
self.SetEventType(EVT_RESULT_ID)
TOTAL = 0
f = open(file, "r")
while f:
line = f.readline()
s = line.split()
n = len(s)
if n == 0:
break
try:
TOTAL += float( s[ n-1 ] )
except:
pass
print TOTAL,line,file
uu = f.read()
print "self str start"
print uu,file,data
f.close()
class WorkerThread(Thread):
def __init__(self, notify_window, exe,file):
"""Init Worker Thread Class."""
Thread.__init__(self)
self._notify_window = notify_window
self.exe = exe
self.file = file
self.start()
def run(self):
f = open(self.file, 'w')
p = subprocess.Popen(exe, shell=False, stdout=subprocess.PIPE)
f.close()
self.str = p.stdout.readline()
print "create file"
print self.str,self.file
wx.PostEvent(self._notify_window, ResultEvent(self.str,self.file))
结果是“创建文件”正确后打印。有一些写入文件的东西。 ResultEvent中的打印错误。我得到TOTAL为0,我也检查了它是空的文件。
答案 0 :(得分:1)
您的代码有几个问题:
1)您正在调用Popen但不等待它完成 - 其余代码可能在管道创建完成之前执行。接下来你要做的就是关闭你用于stdout的文件,这就是为什么它总是空的。在关闭f之前,请致电p.wait()
等待该过程完成。
2)while f:
将永远循环(或直到你突破循环或抛出和异常)。与大多数对象一样,文件始终被视为True。这可能不是你的意思。
3)readline()调用是不必要的,因为文件对象是可迭代的。它更加pythonic(和更安全):
for line in f:
do stuff with line
4)代码从文件中读取行,直到你遇到一个空行(即len(line.split())== 0)。如果您的文件中间某处有一个空行,则只能获得部分文件的总数。
5)在您遍历文件后调用f.read()
。这只会从文件中的当前位置读取结束,因此如果您已经读取了文件中的所有行,则不会读取任何内容。如果您想在此时读取整个文件,请回头查看或关闭并重新打开文件。
6)s[n-1]
是不必要的。使用s[-1]
获取列表中的最后一个元素。
答案 1 :(得分:0)
要将命令作为子进程执行,如果命令执行失败,还应使用此语法检查:
pipe = subprocess.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True)
stdout, stderr = pipe.communicate()
exitcode = pipe.returncode
此外,您不需要在执行命令之前和命令执行之后打开文件(这意味着什么?)。