1

とを使用SplFileObjectLimitIteratorて、大きなファイルの位置xからyまでのコンテンツを読み取ります。

これは、のようなファイルパスを使用する場合に完全に機能します/home/devel/stuff/myfile.log

そのようなパスを使用するhttp://mydomain.com:8090/devel/stuff/myfile.logと機能しません。ただし、パスは正しいです。

絶対パスを使用するとこれは失敗しますか?


エラーメッセージは次のとおりです。

PHP Warning: SplFileObject::rewind() [<a href='splfileobject.rewind'>splfileobject.rewind</a>]: stream does not support seeking in ...

PHP Fatal error: Uncaught exception 'RuntimeException' with message 'Cannot rewind file ...'


完全なコード:

  // $pStrFile contains the valid (yes!) path
  $oFile = new SplFileObject($pStrFile);
  // $nFrom = 80 and $nLines = 30
  $fileIterator = new LimitIterator($oFile, $nFrom, $nLines);

  foreach($fileIterator as $line) {
      $strLines .= $line;
  }
4

2 に答える 2

4

rewind()関数を on で動作させるSplFileObjectには、基になるストリームラッパーがシークをサポートする必要があります。

PHP の現在のHTTP ストリーム ラッパーは、シークをサポートしていません。したがって、次のエラー メッセージが表示されます。

PHP 警告: SplFileObject::rewind() [splfileobject.rewind]: ストリームはシークをサポートしていません ...

私の頭に浮かんだ最初のアイデアNoRewindIteratorは、呼び出しを無効にするだけrewind()でエラーのトリガーを防ぐ を使用することでした。

$obj      = new SplFileObject('http://www.stackoverflow.com/');
$norewind = new NoRewindIterator($obj);
$limit    = new LimitIterator($norewind, 80, 30);

rewind()しかし、もう無いので、そのLimitIterator方も何だかだまされてしまいます。その結果、offsetパラメータが無視されます。80 のオフセットではなく、ゼロ (オフセットなし) になります。

これを克服するために、aCachingIteratorをミックスに挿入できます。それはまさにその問題を解決します:

$obj      = new SplFileObject('http://www.stackoverflow.com/');
$norewind = new NoRewindIterator($obj);
$caching  = new CachingIterator($norewind);
$limit    = new LimitIterator($caching, 80, 30);

foreach ($limit as $i => $line)
{
    printf("%03d: %s", $i, $line);
 }

出力例 ( Demo ):

080: 
081: </span>
082:                 </div>
083:                 <div id="hsearch">
084:                     <form id="search" action="/search" method="get" autocomplete="off">
085:                     <div>

ご覧のとおり、技術的には、PHP SPL には十分な内部ツールが付属しており、HTTP ストリーム用の一時ファイルへの書き込みを省くことができます。ただし、ここでのイテレータはフォワード専用であり、一度しか使用できないことに注意してください。

于 2012-12-11T21:24:01.890 に答える
3

これは、http ラッパーの制限です。ファイルがディスク上にある場合、どの位置からでもアクセスできます。ファイルの途中から読み始めたい場合は、それが可能です。ただし、ファイルが Web サーバー上にあり、HTTP で取得する場合、ファイルの途中を読み取るのは少し難しくなります。

ファイルを一時的な場所にコピーしてから、その上で LimitIterator を使用できます。

于 2012-07-03T10:43:26.417 に答える