1

次のように作成されたファイルポインターを使用して、バイナリファイルを大量に呼び出して呼び出すfreadスクリプトがあります。fseek

$fp = fopen('r','mybinaryfile');

スクリプトは、バイナリ内の約 2,500 個の個別のファイルを処理します。各ファイルは多数のfseekandfread呼び出しを引き付けます。そのため、ファイル ポインターに対する操作の合計は、おそらく 20,000 をはるかに超えます。

ファイル ポインタを使用したこれらの呼び出しのそれぞれが$fp、ディスク上での物理的な読み取りアクションになると考えるのは正しいでしょうか?

もしそうなら、ファイル全体をメモリにロードして、そのように操作する方が良いのではないかと思います。そうでしょうか?

現在、このスクリプトを実行すると、約 20 秒かかります。私には改善の余地があるように思えます。

編集:また、ファイルをメモリに入れることができる場合、ポインターアプローチに固執しながら、それはどのように達成されますか? ファイルはそれぞれ約 3MB しかないため、メモリ不足は問題になりません。

4

3 に答える 3

1

$fp ファイル ポインタを使用したこれらの呼び出しのそれぞれが、ディスク上での物理的な読み取りアクションをもたらすと考えるのは正しいですか?

いいえ、必ずしもそうではありません。OS はファイルをメモリにバッファリングするため、読み取りと書き込みがすぐにディスクにヒットする必要はありません。OSもこれを行うのに非常に優れています。

ファイル全体をメモリに読み込み、ファイル ストリームを使用して操作できる方法を次に示します。

$content = file_get_contents('large_file.bin');
$membuf = fopen("php://memory", "w+b");
fputs($membuf, $content);
unset($content);
rewind($membuf);

// now you can read and seek on $membuf using the usual stream functions fseek, fread etc
于 2012-04-23T01:58:42.890 に答える
0

ファイル全体を文字列または配列として変数に読み込むことで、ファイル全体をメモリに格納します。好きなことをしてから、書き直してください。唯一の問題は、PHP スクリプトがメモリ内で動作している間に他の誰かがファイルを編集する可能性があることです。そのため、ファイルを読み取った後はファイルをロックし、書き込む前にロックを解除することをお勧めします。

于 2012-04-23T01:53:12.627 に答える
0

ファイルを格納するのに十分なメモリがある限り、(1 回限りの操作ではなく) ファイルに対して多くの処理を行う場合は、バイナリをメモリにロードすることをお勧めします。

PHPでは、ファイルをメモリにロードするには、次を使用できますfile_get_contents

file_get_contents http://php.net/file_get_contents

$content = file_get_contents('mybinaryfile');

// $content is a string containing the whole content of your binary

その後、配列参照を使用してファイルの任意の場所を「指す」ことができます。

$content[100]; // the 101th character of your binary

完了したら、書き戻すには、file_put_contents http://php.net/file_put_contentsを使用します。

file_put_contents('mybinaryfile', $content);
于 2012-04-23T01:54:01.633 に答える