2012-07-25 64 views
-1

我想要做到這一點確切的功能,只想要能夠顯示文件的最後20行?fgetcsv/fopen反向

$file = fopen("/tmp/$importedFile.csv","r"); 
    while ($line = fgetcsv($file)) 
    { 
     $i++; 
     $body_data['csv_preview'][] = $line; 
     if ($i > 20) break; 
    } 
    fclose($file); 

我曾試圖改變"r"$file = fopen("/tmp/$importedFile.csv","r");但它似乎只存在哪裏把具有讀指針和寫的變化。

我覺得這可能很簡單。我很抱歉。

回答

1

執行此操作的一種方法是使用SqlFileObject。首先,你需要知道多少行的文件,就可以計算出像這樣的:

$filename = "/tmp/$importedFile.csv"; 

// Create a new object for the file 
$file = new SplFileObject($filename, "r"); 

$lines = 0; 
while (!$file->eof()) { 
    $file->fgets(); 
    $lines++; 
} 

現在你知道有$lines號文件中的行。然後,你必須尋找到$lines - 20行號,並閱讀您的CSV數據,直到EOF,像這樣:

$file->seek($lines - 20); 
while (!$file->eof()) { 
    $body_data['csv_preview'][] = $file->fgetcsv(); 
} 

或許有計算$lines更有效的方式。另外,在嘗試seek()$lines - 20之前,您應該確認文件中有超過20行。

1

您的代碼返回前20行。嘗試修改它最後20行

if($i > 20) 
    array_shift($body_data['csv_preview']) 
0

這是一種方式

$fileend = array(); 
$file = fopen("/tmp/$importedFile.csv","r"); 
while ($line = fgetcsv($file)) 
{ 
    // we have a line, so if $fileend already contains the required number 
    // of lines we have to make some room. 
    if (count($fileend) > 20) { 
     $fileend=array_shift($fileend); 
    } 
    // add freshly read line to array's end 
    array_push($fileend,$line); 
} 
fclose($file); 
// at this point $fileend will contain the 20 last lines of the file. 

我不能向你保證,這將是令人眼花繚亂的快速,但...

一個muich更快的方式將將行存儲在固定大小的循環緩衝區中,這比它聽起來容易

$i=0; 
while ($line = fgetcsv($file)) 
{ 
    // store as linenumber modulo 20 'th element in array 
    $circularbuffer[$i % 20] = $line; 
    $i++; 
} 

然後讀它

// must start reading after last written element, $i has the correct value. 
// and we will read 20 times - same modulo calculation to "circulate" buffer 
for ($j=$i;$j<$i+20;$j++) { 
    $body_data['csv_preview'][] = $circularbuffer[$j%20]; 
} 

顯然這裏的一大優勢是,你讀的文件只有一次,我認爲讀操作是迄今爲止最昂貴的(執行時間)的部分功能。

1

我想出了這一點:

$file = fopen("/tmp/$importedFile.csv","r"); 
$start = count(file($file)) - 20; 
$i = 0; 
while ($line = fgetcsv($file)) { 
    $i++; 
    if ($i > $start) $body_data['csv_preview'][] = $line; 
} 
fclose($file); 
//Body_data has now the last 20 lines. 

希望這有助於

+0

+1(從來沒有使用過該文件()函數),但你可以進一步簡化,很多僅僅閱讀從過去的20種元素'file($ file)'生成的數組,然後使用'str_getcsv'來解析行,不需要重新讀取文件。唯一潛在的缺點是需要讀取大量csv文件時會消耗的內存。 – fvu 2012-07-25 14:38:05