1

重複の可能性:
subprocess.Popen.stdout-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);

これを書き直して、出力全体を出力に保存する必要がなく、ストリームとして処理する方法はありますか?

4

2 に答える 2

1

fileオブジェクトから読み取ることができますp.stdout

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

このアプローチは、Popenオブジェクトに最大で 1 つのパイプがある場合にのみ安全であることに注意してください。それ以上のプロセスは、入力または stderr への書き込みの待機をブロックする可能性があります。その場合pollselectまたはスレッドを使用してパイプを多重化する必要があります。

于 2012-10-31T10:43:30.710 に答える
1

オブジェクトの属性を select呼び出して、プロセスが完了するまでポーリングすることができます。例えば:stdoutPopen

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 に答える