28

fopenで非常に適度なサイズのファイルを読み込もうとすると失敗しますPHPA 6 meg file周りの小さなファイルは問題ありませんが、チョークします100kPHP20 GB を超えるファイルを読み取るために、フラグを使用して再コンパイルする必要がある場合があることを読んだことがあり-D_FILE_OFFSET_BITS=64ますが、6 MB のファイルに問題はありませんか? 最終的には、約 100 MB のファイルを読み込む必要があります。小さいファイルでできるように、それらを開いて fgets を使用して 1 行ずつ読み込むことができると便利です。

で非常に大きなファイルの読み取りと操作を行うためのトリック/ソリューションは何PHPですか?

更新: 6 MB のファイルで失敗する単純なコードブロックの例を次に示します。PHP はエラーをスローしていないようで、false を返すだけです。ひょっとして私は非常にばかげたことをしているのだろうか?

$rawfile = "mediumfile.csv";

if($file = fopen($rawfile, "r")){  
  fclose($file);
} else {
  echo "fail!";
}

別の更新: ご協力いただきありがとうございます。それは信じられないほどばかげたものであることが判明しました - パーミッションの問題です。大きなファイルには許可されていないのに、私の小さなファイルには不可解にも読み取り許可がありました。どっ!

4

8 に答える 8

55

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、スクリプトが実行されている場所に対して相対的ですか? おそらく、ここでファイル名の絶対パスを設定してみてください。

于 2008-10-02T13:29:17.193 に答える
11

1.3GB のファイルと 9.5GB のファイルで 2 つのテストを行いました。

1.3GB

使用するfopen()

このプロセスは、計算に 15555 ミリ秒を使用しました。

システムコールで 169 ミリ秒を費やしました。

使用するfile()

このプロセスは、計算に 6983 ミリ秒を使用しました。

システムコールで 4469 ミリ秒を費やしました。

9.5GB

使用するfopen()

このプロセスは、計算に 113559 ミリ秒を使用しました。

システムコールで 2532 ミリ秒を費やしました。

使用するfile()

このプロセスは、計算に 8221 ミリ秒を使用しました。

システム コールで 7998 ミリ秒を費やしました。

より速いようfile()です。

于 2015-10-07T20:17:25.143 に答える
1

ファイルを出力するだけの場合は、 readfile 関数を使用してみてください。

そうでない場合は、アプリケーションの設計について考える必要があるかもしれませんが、なぜ Web 要求でこのような大きなファイルを開く必要があるのでしょうか?

于 2008-10-02T13:16:57.707 に答える
1

ビデオ ストリーミング サーバーとして php スクリプトを使用して、fopen を使用してストリーミング用のビデオ ファイルを開きましたが、サイズが 50/60 MB を超えるファイルでも問題はありませんでした。

于 2008-10-02T13:21:46.617 に答える
0

メモリ制限に達したことが原因で問題が発生した場合は、より高い値を設定してみてください(これは、phpの構成によっては機能する場合と機能しない場合があります)。

これにより、メモリ制限が12Mbに設定されます

ini\_set("memory_limit","12M");
于 2008-10-02T14:13:05.947 に答える
0

私にとっては、fopen()1MBを超えるファイルでは非常に遅く、file()はるかに高速です。

一度に 100 行を読み取ってバッチ挿入を作成しようとすると、4 秒fopen()かかるのに対して 37 秒かかります。そのステップが組み込まれてfile()いる必要がありますstring->arrayfile()

すべてのファイル処理オプションを試して、アプリケーションで最適に機能するオプションを確認します。

于 2014-08-04T16:34:36.460 に答える
-1

file() を試しましたか?

http://is2.php.net/manual/en/function.file.php

または file_get_contents()

http://is2.php.net/manual/en/function.file-get-contents.php

于 2008-10-02T13:28:44.387 に答える