如何使用 PHP 获取 CSV 文件中的总行数?

Posted

技术标签:

【中文标题】如何使用 PHP 获取 CSV 文件中的总行数?【英文标题】:How can I get the total number of rows in a CSV file with PHP? 【发布时间】:2014-02-22 05:09:46 【问题描述】:

我正在使用这种方法,但可以让它正常工作。

if (($fp = fopen("test.csv", "r")) !== FALSE)  
  while (($record = fgetcsv($fp)) !== FALSE) 
      $row++;
  

  echo $row;

【问题讨论】:

这种解决方案应该可以工作,但问题可能是“while(record...) 位;它在空行上中断。注意;提供的解决方案都没有计算文件是可靠的,因为它们只计算行数,而不是 csv 条目(可以包含换行符) 【参考方案1】:

使用SplFileObject 创建一个新的文件引用:

$file = new SplFileObject('test.csv', 'r');

尝试seekphp 可以处理的最高 Int:

$file->seek(PHP_INT_MAX);

然后实际上它会寻找文件中的最高行,这是你的最后一行,最后一行 + 1 等于你的总行数:

echo $file->key() + 1;

很棘手,但这会避免您将文件内容加载到内存中,这在处理非常大的文件时是一件非常酷的事情。

【讨论】:

太棒了,效果很好,这应该是最佳答案。 适用于 PHP >= 5.1 - 内存效率高。使用$file->rewind() 回到文件的开头。 最佳答案在这里 @LeoCavalcante 我最终不得不使用这种标志组合来让它工作(在 Windows 上)$file->setFlags(SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE); 与之前加载整个文件的“解决方案”类似的问题:您只会计算物理行,而 csv 文件可以轻松包含作为内容一部分的换行符;所以结果会出现偏差。【参考方案2】:

这是另一个使用file() 将整个文件读入数组、自动解析新行等的选项:

$fp = file('test.csv');
echo count($fp);

此外,从 PHP5 开始,您可以传入 FILE_SKIP_EMPTY_LINES... 以跳过空行,如果您愿意:

$fp = file('test.csv', FILE_SKIP_EMPTY_LINES);

手册: http://php.net/manual/en/function.file.php

【讨论】:

这适用于小文件。如果您有一个巨大的 CSV 文件(GB 大小),使用 file() 读取整个文件并使用 count() 可能不是一个好主意,因为它将文件存储在内存中,并且可能会挂起内存不足的系统。 @TanHongTat 有更有效的方法吗? @xd6_ this answer 对于大文件会更有效 请注意,因为 CSV 列的值可能包含换行符,所以没有简单的方法可以覆盖 100% 的简单情况。这意味着要获得文件中真实数量的“记录”,您实际上必须解析文件。【参考方案3】:

试试

$c =0;
$fp = fopen("test.csv","r");
if($fp)
    while(!feof($fp))
          $content = fgets($fp);
      if($content)    $c++;
    

fclose($fp);
echo $c;

【讨论】:

【参考方案4】:

我知道这已经很老了,但实际上我遇到了同样的问题。 作为一种解决方案,我假设使用 linux 特定的逻辑:

$rows = shell_exec('$(/bin/which cat) file.csv | $(/bin/which tr) "\r" "\n" | $(which wc) -l');

注意:这仅适用于 linux,并且仅当您 100% 确定您的文件没有多行单元格时才应使用它

【讨论】:

【参考方案5】:

CSV 行由换行符分隔。因此,用换行符分割行,你会得到一个行数组,它是可数的。

if (($fp = fopen("test.csv", "r")) !== FALSE)  
    $rows = explode("\n", $fp);
    $length = count($rows);

    echo $length;

【讨论】:

您实际上并没有从文件指针中读取。如果您只是计算行数,那么count(file("test.csv")) 会更快地实现它。然而,在某些 CSV 变体中,引用的值可能包含换行符。【参考方案6】:

注意;对文件中的行数进行计数的更高评价的解决方案都不可靠,因为它们只计算行数,而不是 csv 条目(可以包含换行符)

我正在使用与 op 类似的解决方案,并且效果很好,但是使用 op 的代码时,while 部分可能会在空行上中断,这可能是他的问题。

所以它看起来像这样(编辑过的操作代码)

$rowCount=0;
if (($fp = fopen("test.csv", "r")) !== FALSE) 
  while(!feof($fp)) 
    $data = fgetcsv($fp , 0 , ',' , '"', '"' );
    if(empty($data)) continue; //empty row
    $rowCount++;
  
  fclose($fp);

echo $rowCount;

【讨论】:

这不是和this answer from two years ago本质上一样吗? 谢谢,@Robbie Averill 老实说,我不确定它是否会在所有情况下导致相同的结果 - 最值得注意的是,空行。我有一种感觉,另一个答案只会计算空行,而这个肯定不会。对我跳过审查负面评价的答案感到羞耻,它确实相当接近。【参考方案7】:

我觉得这个最靠谱:

$file = new SplFileObject('file.csv', 'r');
$file->setFlags(
    SplFileObject::READ_CSV |
    SplFileObject::READ_AHEAD |
    SplFileObject::SKIP_EMPTY |
    SplFileObject::DROP_NEW_LINE
);

$file->seek(PHP_INT_MAX);

$lineCount = $file->key() + 1;

【讨论】:

如果有解释,我可能会赞成。我有反对支持 sn-p 转储的政策——即使它们有帮助/很好。【参考方案8】:

我知道这是一篇旧帖子,但我一直在谷歌搜索这个问题,发现原始代码的唯一问题是 您需要在 while 循环之外定义 $row ,像这样:

if (($fp = fopen("test.csv", "r")) !== FALSE)  
$row = 1;
  while (($record = fgetcsv($fp)) !== FALSE) 
      $row++;
  

以防万一它对某人有帮助:) 回声$行;

【讨论】:

【参考方案9】:

如果您从表单中获取文件

$file = $_FILES['csv']['tmp_name'];
                $fp = new SplFileObject($file, 'r');
                $fp->seek(PHP_INT_MAX);
                echo $fp->key() + 1;
                $fp->rewind();

像魅力一样工作!!!!!!!!!!!!!!!!!!

【讨论】:

【参考方案10】:
$filename=$_FILES['sel_file']['tmp_name'];
$file=fopen($filename,"r");
$RowCount=0;

while ((fgetcsv($file)) !== FALSE) 

    $RowCount++;


echo $RowCount;
fclose($file);

【讨论】:

添加一些解释,说明此答案如何帮助 OP 解决当前问题

以上是关于如何使用 PHP 获取 CSV 文件中的总行数?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SSIS 将 File1 标头中的单个值与 File2 中的总行数进行比较(csv)

如何获取DataGrid的总行数

将大型 .csv 文件导入 Excel,

ExtJS:返回 json 存储中的总行/记录

php获取代码总行数

如何在特定模式中的所有表的选择列表中获取总行数和最大(时间戳)列