2012-07-03 79 views
1

我用SplFileObjectLimitIterator讀取,直到一個大文件的y的位置x的內容。PHP LimitIterator失敗(「不支持查找」 +「無法倒帶文件」)

當使用像/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; 
    } 

回答

3

這是一個限制http包裝。如果文件在磁盤上,您可以在任何位置訪問它。如果你想在文件中間開始閱讀,那是可能的。但是,當文件位於Web服務器上並且您使用HTTP獲取時,讀取文件的中間位置有點困難。

你可以將copy這個文件放到一個臨時的位置,然後在其上使用LimitIterator。

+0

那麼這不是我正在尋找的,但它是一個當前有效的解決方案。謝謝。 – Patrick

3

要讓rewind()函數在SplFileObject上工作,底層streamwrapper需要支持查找。

PHP當前HTTP stream wrapper不支持尋求。所以,你得到的錯誤信息:

PHP的警告:SplFileObject ::退()[splfileobject.rewind]:流不支持尋求...

第一個想法進入我的頭腦是使用NoRewindIterator只是禁用rewind()調用,因此防止觸發錯誤。

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

然而,因爲沒有任何rewind()時間越長,LimitIterator是有點上當了。這導致忽略偏移量參數,它不會是80的偏移量,而只是零(無偏移量)。

爲了克服這個問題,可以將CachingIterator插入到混合中。它解決了正是問題:

$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> 

正如你所看到的,在技術上PHPS SPL附帶足夠的內部工具,備用寫爲HTTP流的臨時文件。但請記住,這裏的迭代器只是向前的,這意味着你只能使用它一次。