ホームページ >バックエンド開発 >Python チュートリアル >大きなファイルの最後の N 行を効率的に取得するにはどうすればよいですか?
概要:
大きなログ ファイルを分析する場合、ページネーションや検査のために最後の N 行を取得することが必要になることがよくあります。これにより、オフセットを使用してログ ファイルを効率的に末尾に付ける方法という問題が生じます。
def tail(f, n, offset=0): avg_line_length = 74 to_read = n + offset while 1: try: f.seek(-(avg_line_length * to_read), 2) except IOError: f.seek(0) pos = f.tell() lines = f.read().splitlines() if len(lines) >= to_read or pos == 0: return lines[-to_read:offset and -offset or None] avg_line_length *= 1.3
評価:
これこのアプローチでは、行の平均長についての仮定が立てられ、十分な行が見つかるまで段階的に後方に探索されます。初期見積もりにより、シークを複数回行う必要があり、パフォーマンスが低下する可能性があります。
def tail(f, lines=20): BLOCK_SIZE = 1024 f.seek(0, 2) block_end_byte = f.tell() lines_to_go = lines block_number = -1 blocks = [] while lines_to_go > 0 and block_end_byte > 0: if (block_end_byte - BLOCK_SIZE > 0): f.seek(block_number * BLOCK_SIZE, 2) blocks.append(f.read(BLOCK_SIZE)) else: f.seek(0, 0) blocks.append(f.read(block_end_byte)) lines_found = blocks[-1].count('\n') lines_to_go -= lines_found block_end_byte -= BLOCK_SIZE block_number -= 1 all_read_text = ''.join(reversed(blocks)) return '\n'.join(all_read_text.splitlines()[-lines:])
説明:
このメソッドは、必要な数の改行が見つかるまで、ファイルをブロックごとにバックトラックします。行の長さについての仮定は行わず、ファイルが小さすぎて後戻りできない場合は最初から読み取ります。
一般に、候補ソリューション 2 は候補ソリューション 1 よりも効率的で堅牢です。推定に依存せず、ファイルを順番に読み取るためです。これは、オフセットを使用してログ ファイルを追跡するためのより信頼性の高いアプローチです。
以上が大きなファイルの最後の N 行を効率的に取得するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。