最初の問題は、currentx.read()
1 つの巨大な文字列を返すことです。そのため、それをループすると、ファイル内の各行ではなく、その文字列内の各文字がループされます。
次のように、ファイルを文字列の巨大なリストとしてメモリに読み込むことができます。
current_data = list(currentx)
ただし、これは、一度に 1 行ずつファイルを反復処理するより (Python に適切なサイズのバッファーを選択させるのではなく、ファイル全体にメモリを割り当てるのに時間を浪費するため)、ファイル全体を一度に処理するよりも遅くなることがほぼ保証されています (行を分割するのに時間を無駄にしているからです)。言い換えれば、この方法では両方の世界で最悪の事態が発生します。
したがって、行のイテレータとして保持するか:
next(currentx) # skip a line
for line in currentx:
# do something with each line
…または文字列として保持し、最初の行を分割します。
current_data = currentx.read()
first, _, rest = current_data.partition('\n')
# do something with rest
一度にファイルを読み書きするのが遅すぎることが判明した場合はどうなるでしょうか (これはおそらく、書き込み前に初期ブロックを強制的にキャッシュから追い出し、インターリーブを防ぎ、メモリの割り当てに時間を無駄にします)。一度に実行するのも遅すぎます (可能性は低いですが、不可能ではありません。改行の検索、小さな文字列のコピー、および Python でのループは無料ではありません。CPU 時間は I/O 時間よりもはるかに安いため、めったに重要ではありません)?
あなたができる最善の方法は、理想的なブロックサイズを選択し、バッファリングされていない読み取りと書き込みを自分で行い、最初の改行が見つかるまで時間を無駄にするだけです。
最初の行がブロック サイズよりも長くならないと仮定できる場合、これは非常に簡単です。
BLOCK_SIZE = 8192 # a usually-good default--but if it matters, test
with open(inpath, 'rb', 0) as infile, open(outpath, 'wb', 0) as outfile:
buf = infile.read(BLOCK_SIZE)
first, _, rest = buf.partition(b'\n')
outfile.write(rest)
while True:
buf = infile.read(BLOCK_SIZE)
if not but:
break
outfile.write(buf)
これを複数回行う場合は、ブロック ファイル イテレータ関数を作成します (または、事前にテスト済みのレシピを探したほうがよいでしょう。それらは ActiveState やメーリング リストのいたるところにあります)。