php统计txt文件有多少行,有效地计算文本文件的行数。 (200MB +)

这篇博客探讨了在处理大文件时如何有效地计算行数,避免一次性加载整个文件到内存中。通过使用fgets()函数逐行读取并计数,以及在*nix系统上利用wc命令,提出了多种解决方案。文章比较了不同方法的性能和适用场景,包括使用Perl和wc-l命令的技巧,以及PHP的SplFileObject和生成器。此外,还讨论了内存管理和文件处理的最佳实践。
摘要由CSDN通过智能技术生成

这将使用较less的内存,因为它不会将整个文件加载到内存中:

$file="largefile.txt"; $linecount = 0; $handle = fopen($file, "r"); while(!feof($handle)){ $line = fgets($handle); $linecount++; } fclose($handle); echo $linecount;

fgets将单行加载到内存中(如果省略了第二个参数$length ,它将继续读取stream,直到到达行的末尾,这就是我们想要的)。 如果你关心墙上的时间和内存的使用情况,那么这个速度还不如使用PHP以外的速度。

唯一的危险是,如果任何行都特别长(如果遇到没有换行符的2GB文件,该怎么办?)。 在这种情况下,你最好把它捣成块,然后计算结束字符:

$file="largefile.txt"; $linecount = 0; $handle = fopen($file, "r"); while(!feof($handle)){ $line = fgets($handle, 4096); $linecount = $linecount + substr_count($line, PHP_EOL); } fclose($handle); echo $linecount;

使用fgets()调用循环是很好的解决scheme,而且最直接的写法是:

即使内部使用8192字节的缓冲区读取文件,您的代码仍然需要为每行调用该函数。

如果您正在读取二进制文件,则在技术上可行的是,一行可能比可用内存大。

该代码以8kB为单位读取一个文件,然后统计该块内的换行数。

function getLines($file) { $f = fopen($file, 'rb'); $lines = 0; while (!feof($f)) { $lines += substr_count(fread($f, 8192), "\n"); } fclose($f); return $lines; }

如果每行的平均长度至多为4kB,则您将已经开始保存函数调用,并且在处理大文件时这些累加起来。

基准

我用1GB的文件进行了testing; 这里是结果:

+-------------+------------------+---------+ | This answer | Dominic's answer | wc -l | +------------+-------------+------------------+---------+ | Lines | 3550388 | 3550389 | 3550388 | +------------+-------------+------------------+---------+ | Runtime | 1.055 | 4.297 | 0.587 | +------------+-------------+------------------+---------+

时间是以秒为单位的实时测量,请参阅这里真实的意思

如果你正在Linux / Unix主机上运行,​​最简单的解决方法是使用exec()或类似命令运行命令wc -l $path 。 只要确保你已经清理了$path ,以确保它不是像“/path/到/文件; rm -rf /”。

有一种更快的方式,我发现不需要循环整个文件

只在* nix系统上,窗口上可能有类似的方法…

$file = '/path/to/your.file'; //Get number of lines $totalLines = intval(exec("wc -l '$file'"));

简单的面向对象的解决scheme

$file = new \SplFileObject('file.extension'); while($file->valid()) $file->fgets(); var_dump($file->key());

更新

另一种方法是在SplFileObject::seek方法中使用PHP_INT_MAX 。

$file = new \SplFileObject('file.extension', 'r'); $file->seek(PHP_INT_MAX); echo $file->key() + 1;

如果您使用PHP 5.5,则可以使用生成器 。 这在5.5之前的任何版本的PHP中都不起作用。 从php.net:

“生成器提供了一种简单的方法来实现简单的迭代器,而无需实现实现Iterator接口的类的开销或复杂性。”

// This function implements a generator to load individual lines of a large file function getLines($file) { $f = fopen($file, 'r'); // read each line of the file without loading the whole file to memory while ($line = fgets($f)) { yield $line; } } // Since generators implement simple iterators, I can quickly count the number // of lines using the iterator_count() function. $file = '/path/to/file.txt'; $lineCount = iterator_count(getLines($file)); // the number of lines in the file

这是Wallace de Souza解决scheme的补充

计数时还跳过空行:

function getLines($file) { $file = new \SplFileObject($file, 'r'); $file->setFlags(SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE); $file->seek(PHP_INT_MAX); return $file->key() + 1; }

你有几个select。 首先是增加可用的内存允许,这可能不是最好的办法做事情,因为你说的文件可以变得非常大。 另一种方法是使用fgets逐行读取文件,并增加一个计数器,这个计数器根本不应该引起任何内存问题,因为任何时候只有当前行在内存中。

private static function lineCount($file) { $linecount = 0; $handle = fopen($file, "r"); while(!feof($handle)){ if (fgets($handle) !== false) { $linecount++; } } fclose($handle); return $linecount; }

我想为上面的函数添加一点点修正…

在一个特定的例子,我有一个文件包含单词“testing”该函数返回2作为结果。 所以我需要添加一个检查,如果fgets返回false或不:)

玩的开心 :)

还有另一个答案,我认为这可能是一个很好的补充列表。

如果你已经安装了perl ,并且能够在PHP中运行shell:

$lines = exec('perl -pe \'s/\r\n|\n|\r/\n/g\' ' . escapeshellarg('largetextfile.txt') . ' | wc -l');

这应该处理大多数换行符,无论是从Unix或Windows创build的文件。

两个缺点(至less):

1)让你的脚本如此依赖于它运行的系统是不是一个好主意(假设Perl和wc可用是不安全的)

2)只是在逃跑的一个小错误,你已经交给你的机器上的shell访问。

就我所了解的大多数事情(或者认为我知道的)而言,我从别的地方得到了这个信息:

约翰里夫文章

public function quickAndDirtyLineCounter() { echo "

" . $folder . "" . $file . "" . $linecount . "
"; }

为了计算这些线,使用:

$handle = fopen("file","r"); static $b = 0; while($a = fgets($handle)) { $b++; } echo $b;

基于罗杰多米诺的解决scheme,这里是我使用的(它使用wc,如果可用的话,否则回落到主宰罗杰的解决scheme)。

class FileTool { public static function getNbLines($file) { $linecount = 0; $m = exec('which wc'); if ('' !== $m) { $cmd = 'wc -l < "' . str_replace('"', '\\"', $file) . '"'; $n = exec($cmd); return (int)$n + 1; } $handle = fopen($file, "r"); while (!feof($handle)) { $line = fgets($handle); $linecount++; } fclose($handle); return $linecount; } }

我使用这个方法来纯粹地计算一个文件中有多less行。 做这个经文的其他答案的缺点是什么? 我看到很多行,而不是我的两行解决scheme。 我猜这是没有人做的。

$lines = count(file('your.file')); echo $lines;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值