1

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

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

我尝试过更改 "r"in$file = fopen("/tmp/$importedFile.csv","r");但是似乎只有将指针放置在何处进行读写的变化。

我觉得这可能是一件容易的事。我很抱歉。

4

4 回答 4

2

一种方法是使用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。此外,您应该先确认文件中有超过 20 行,然后再seek()尝试$lines - 20.

于 2012-07-25T13:42:28.030 回答
1

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

if($i > 20)
   array_shift($body_data['csv_preview'])
于 2012-07-25T13:39:34.210 回答
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.

希望这可以帮助

于 2012-07-25T14:13:59.953 回答
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];
}

显然,这里最大的优势是您只读取文件一次,并且我认为读取操作是该函数迄今为止最昂贵的(执行时间)部分。

于 2012-07-25T13:41:01.280 回答