1

可能重复:
subprocess.Popen.stdout - 再次实时读取标准输出!

我正在处理二进制文件的输出,但我使用临时字符串来表示输出。由于理论上输出可能相当大,我更愿意使用 unpack 或 unpack_from 将输出作为流处理。

代码是这样的:

file = '/home/t/FinancialData/GBPUSD/2007/05/01/20070501_01h_ticks.bi5';
command = ('lzma', '-kdc', '-S', 'bi5', file);
p = subprocess.Popen(command, stdout=subprocess.PIPE);
out, err = p.communicate();
for s in (out[x:x+20] for x in range(0, len(out), 20)):
    values = struct.unpack(">3L2f", s)
    with open(csvfilename, 'wb') as csvfile:
        csvwriter = csv.writer(csvfile, delimiter=',',
                               quotechar='|', quoting=csv.QUOTE_MINIMAL)
        csvwriter.writerow(values);

有没有办法重写它,所以它不必将整个输出存储在 out 中,而是将其作为流处理?

4

2 回答 2

1

您可以从file对象中读取p.stdout

while True:
    s = p.stdout.read(20)
    if not s:
        break
    values = struct.unpack(">3L2f", s)
    ...

请注意,只有在对象上最多有一个管道时,这种方法才是安全的Popen;任何更多,该过程可能会阻止等待输入或写入stderr。在这种情况下,您应该使用poll,select或 threading 来多路复用管道。

于 2012-10-31T10:43:30.710 回答
1

您可以select围绕对象的stdout属性进行 调用Popen并轮询,直到该过程完成。例如:

from subprocess import Popen, PIPE
from select import select

cmd = ('lzma', '-kdc', '-S', 'bi5', 'path/to/datafile')
p = Popen(cmd, stdout=PIPE)

while p.poll() == None:
    r,w,e = select([p.stdout], [], [])
    if r:
        data = p.stdout.read(512)
        # unpack and append to csv file ...

干杯,

于 2012-10-31T10:56:14.663 回答