反向fgetcsv / fopen

时间:2012-07-25 13:30:50

标签: php codeigniter csv

我正在尝试做这个确切的功能,只希望能够显示文档的最后20行?

    $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");,但似乎只有将指针放在读写位置的变体。

我觉得这可能很简单。我道歉。

4 个答案:

答案 0 :(得分:1)

您的代码返回前20行。尝试修改最后20行

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

答案 1 :(得分: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行。

答案 2 :(得分: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.

希望这有帮助

答案 3 :(得分: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.

我无法向你保证,虽然它会很快......

更快的方法是将线存储在固定大小的循环缓冲区中,这比听起来更容易

$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];
}

显然,这里最大的优点是你只读了一次文件,而且我认为读操作是迄今为止功能最昂贵的(执行时)部分。