2

数百万行のテキストを含む100GBのtxtファイルがあることを考慮してください。PHPを使用してこのテキストファイルを行のブロックごとに読み取るにはどうすればよいですか?

file_get_contents();ファイルが大きすぎるので使えません 。fgets() また、テキストを1行ずつ読んでください。これにより、ファイル全体の読み取りが完了するまでに時間がかかる可能性があります。

fread($fp,5030)ここで、「5030」は読み取る必要のある長さの値を使用する場合。最大長に達したために、行全体(行の途中で停止するなど)を読み取れない場合がありますか?

4

5 に答える 5

4

file_get_contents();を使用できません。ファイルが大きすぎるためです。fgets()は、テキストを1行ずつ読み取ります。これにより、ファイル全体の読み取りが完了するまでに時間がかかる可能性があります。

わからない、なぜあなたは使うことができないはずなのかfgets()

$blocksize = 50; // in "number of lines"
while (!feof($fh)) {
  $lines = array();
  $count = 0;
  while (!feof($fh) && (++$count <= $blocksize)) {
    $lines[] = fgets($fh);
  }
  doSomethingWithLines($lines);
}

とにかく100GBを読むには時間がかかります。

于 2011-07-18T13:03:25.127 に答える
1

このfreadアプローチは合理的な解決策のように聞こえます。文字列の最後の文字が改行文字('\n')であるかどうかを確認することで、行の終わりに到達したかどうかを検出できます。そうでない場合は、さらにいくつかの文字を読み取って既存の文字列に追加するか、文字列から最後の改行まで文字をトリミングしてからfseek、ファイル内の位置を調整するために使用できます。

補足: 100GBのファイルの読み取りには非常に長い時間がかかることをご存知ですか?

于 2011-07-18T13:02:29.527 に答える
1

fread($ fp、somesize)を使用し、行の終わりを見つけたかどうかを手動で確認する必要があると思います。そうでない場合は、別のチャンクを読み取ります。

お役に立てれば。

于 2011-07-18T13:03:13.340 に答える
1

関数内で1行の読み取りを実装し、その特定のステップの実装の詳細をコードの残りの部分から隠すことをお勧めします。処理関数は、行がどのように取得されたかを気にする必要はありません。次に、を使用して最初のバージョンを実装し、遅すぎることに気付いた場合fgets()は他の方法を試すことができます。最初の実装が遅すぎる可能性は十分にありますが、要点は、ベンチマークを実行するまでわからないということです。

于 2011-07-18T13:03:14.580 に答える
0

これは古い質問だと思いますが、最終的にこの質問を見つけた人にとっては、新しい答えの価値があると思います。

100GBを読むには時間がかかることに同意します。そのため、「すでにたくさんある場合、誰がどれだけの量を気にするか」と考えるのではなく、できるだけ少なくするために、それを読むための最も効果的なオプションを見つける必要があることにも同意します。 "だから、可能な限り最短の時間を見つけましょう。

別の解決策:

生データのチャンクをキャッシュする

freadを使用して、そのデータのキャッシュを読み取ります

行ごとに読む

キャッシュからキャッシュの終わりまたはデータの終わりが見つかるまで1行ずつ読み取ります

次のチャンクを読んで繰り返します

チャンクの未処理の最後の部分(行区切り文字を探していた部分)を取得して前に移動し、定義したサイズから未処理のデータのサイズを引いたチャンクを読み取り、その直後に配置します未処理のチャンクを使用すると、新しい完全なチャンクが作成されます。
ファイルが完全に読み取られるまで、行ごとの読み取りとこのプロセスを繰り返します。

予想される行のサイズよりも大きいキャッシュチャンクを使用する必要があります。

キャッシュサイズが大きいほど、読み取りは速くなりますが、使用するメモリは多くなります。

于 2016-12-02T14:10:41.843 に答える