6

私はCとC++のバックグラウンドを持っていますが、いくつかのWeb関連のものでも遊んでいます。私たちすべてのCの人々は(願わくば)、読み取りを行う前feofにaを呼び出すことはエラーであることを知っています。FILE*これは、CおよびC++の初心者を非常に頻繁に刺すものです。これはPHPの実装にも当てはまりますか?

ファイルがソケットか、読み取りを完了する前にサイズを知ることが不可能な他の何かである可能性があるため、それが必要だと思います。しかし、ほぼすべてのPHPの例(私が見たphp.netで見つかったものでさえ)は次のようになります(そしてアラームが頭の中で鳴ります):

$f = fopen("whatever.txt", "rb");
while(!feof($f)) {
    echo fgets($f);
}
fclose($f);

私はこれをこのように書き、この問題を回避することが望ましいことを知っています:

$f = fopen("whatever.txt", "rb");
while($line = fgets($f)) {
    echo $line;
}
fclose($f);

しかし、それは要点を超えています。「間違った方法」で失敗するかどうかをテストしてみましたが、正しく動作しないようにすることができませんでした。これは正確には科学的ではありませんが、試してみる価値があると思いました。

それで、PHPでfeofの前に呼び出すのは間違っていますか?fread

PHPがCのバージョンとは異なる方法でこれを行うことができる方法はいくつかありますが、欠点があると思います。

  • デフォルトで!EOFにすることができます。一部のコーナーケースでは正しくない可能性があるため、これは最適ではありません。

  • 呼び出し中にファイルサイズを取得することはできましたfopenが、これはすべての種類のファイルリソースで機能するわけではなく、一貫性のない動作が発生し、速度が低下します。

4

3 に答える 3

3

PHPは、ファイルから読み取ろうとするまで、ファイルの最後にあるかどうかを認識しません。この簡単な例を試してください。

<?php 
$fp = fopen("/dev/null","rb"); 
while (!feof($fp)) { 
    $data = fread($fp, 1);
    echo "read " . strlen($data) . " bytes";  
} 
fclose($fp); 
?>

1行の読み取り値が表示されread 0 bytesます。技術的にはファイルの最後にいるにもかかわらず、feof()はtrueを返しました。fread($fp, 1)通常、これはデータを返さないため問題にはなりません。その上で実行している処理はすべて、データを正常に処理しません。ファイルの最後にいるかどうかを本当に知る必要がある場合は、最初に読み取りを行う必要があります。

于 2010-07-13T17:17:44.763 に答える
0

これは答えというよりは質問かもしれませんが、file_get_contents()を使用してみませんか?私の経験では、ファイルまたはストリームを読み取っている場合、この関数はダーティな作業を行います(リソース全体を文字列に読み取るか、制限とオフセットを知っている/計算できると仮定します)。その姉妹関数file_put_contents()は、逆にうまく機能します。

たとえば、次の例を示します。

$expected_content = "Hello Stack Overflow!"
$real_content = file_get_contents("/path/to/file.txt");
if ($expected_content != $real_content){
   file_put_contents("/path/to/file.txt", $real_content);
}

またはストリーム:

$expected_content = "Hello Stack Overflow!"
$real_content = file_get_contents("http://host.domain.com/file.txt");
if ($expected_content != $real_content){
   $options = array('ftp' => array('overwrite' => true));
   $stream = stream_context_create($options); 
   file_put_contents("ftp://user:pass@host.domain.com/file.txt", $real_content, 0, $stream);
}

そうすれば、EOFなどについて心配する必要はありません。それはあなたに代わって行います(ftp putは少し厄介ですが、それで問題ありません)。もちろん、これはすべての状況で機能するわけではありません...

このアプローチを実行不可能にする元の質問から私が見逃している何かがありますか?

于 2010-07-13T17:43:48.080 に答える
-1

feofの前に電話をかけないというあなたの主張freadは正しくありません-その結果、質問は無効です。

于 2010-07-13T17:26:06.797 に答える