我正在尝试做这个确切的功能,只希望能够显示文档的最后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");
,但似乎只有将指针放在读写位置的变体。
我觉得这可能很简单。我道歉。
答案 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];
}
显然,这里最大的优点是你只读了一次文件,而且我认为读操作是迄今为止功能最昂贵的(执行时)部分。