9

サイズが ~1GB のタブ区切りファイルを解析しようとしています。

スクリプトを実行すると、次のようになります。

Fatal error: Allowed memory size of 1895825408 bytes exhausted  (tried to allocate 1029206974 bytes) ...

現時点での私のスクリプトは次のとおりです。

$file = file_get_contents('allCountries.txt') ;

$file = str_replace(array("\r\n", "\t"), array("[NEW*LINE]", "[tAbul*Ator]"), $file) ;

php.ini のメモリ制限を -1 に設定すると、次のようになります。

Fatal error: Out of memory (allocated 1029963776) (tried to allocate 1029206974 bytes)

ファイルを部分的に開いてから次の部分に移動して、一度に使用されるメモリを少なくする方法はありますか?

4

4 に答える 4

13

はい、1 行ずつ読むことができます。

$handle = @fopen("/tmp/inputfile.txt", "r");
if ($handle) {
    while (($buffer = fgets($handle, 4096)) !== false) {
        echo $buffer;
    }
    fclose($handle);
}
于 2013-02-13T08:04:18.013 に答える
2

ファイルを読み取るには、ブロックを使用する必要があります。この質問の答えを確認してください。 https://stackoverflow.com/a/6564818/1572528

サイズの小さいファイルにこれを使用することもできます。

ini_set('memory_limit', '32M'); //max size 32m
于 2013-02-13T08:07:43.207 に答える
1

fopenスクリプトのタイムアウト設定ではなく、それが失敗していると確信していますか? 通常、デフォルトは約 30 秒程度です。ファイルの読み込みにそれよりも時間がかかる場合は、それを超えている可能性があります。

考慮すべきもう 1 つのことは、スクリプトのメモリ制限です。ファイルを配列に読み込むと、これを超える可能性があるため、エラー ログでメモリの警告を確認してください。

上記のいずれも問題でない場合はfgets、ファイルを行単位で読み取り、処理しながら処理するために使用することを検討してください。

$handle = fopen("/tmp/uploadfile.txt", "r") or die("Couldn't get handle");
if ($handle) {
    while (!feof($handle)) {
        $buffer = fgets($handle, 4096);
        // Process buffer here..
    }
    fclose($handle);
}

編集

PHP はエラーをスローしていないようで、false を返すだけです。

修正するパスは$rawfile、スクリプトが実行されている場所に対して相対的ですか? おそらく、ここでファイル名の絶対パスを設定してみてください。

于 2013-02-13T08:06:13.770 に答える
1

はい、これには fopen と fread / fgets を使用します。

http://www.php.net/manual/en/function.fread.php

string fread ( resource $handle , int $length )

$length を読み取りたいファイルの数に設定します。$handle は新しい読み取りの位置を保存し、 fseek を使用して後で位置を設定することもできます....

于 2013-02-13T08:07:55.513 に答える