How to get number of lines with SplFileObject?
Solution 1
Why not simply use file handlers and do like in this question? Its simple, fast and very efficient.
If you absolutely must use spl, you can do it like this
$file = new SplFileObject("/path/to/file.txt");
$i = 0;
while (!$file->eof()) {
$i++;
$file->next();
}
print "file has " . $i . " lines";
Solution 2
iterator_count
and line-by-line iterating using next()
is broken in my php version 5.3.7 under Ubuntu.
Also seems broken fseek([any offset], SEEK_END)
method. key()
returns 0.
Iterate over large files using seek($lineCount)
is too slow.
Simpliest 5.3.7-verified way is
// force to seek to last line, won't raise error
$file->seek($file->getSize());
$linesTotal = $file->key();
Counting 30000 lines requires now 0.00002 secs and costs about 20 kb of memory.
Iterations method takes about 3 seconds.
Solution 3
I agree with Николай Конев on using seek function
is much faster than going through the entire file line by line, but as Twisted1919 said using the file size to seek the last line is confusing so my suggestion is use PHP_INT_MAX instead of the file size:
// force to seek to last line, won't raise error
$file->seek(PHP_INT_MAX);
$linesTotal = $file->key();
Solution 4
The SplFileObject
offers an itertor, one iteration per line:
$numberOfLines = iterator_count($file);
The function iterator_count
is your friend here, doing the traversal for you and returning the number of iterations.
You can make use of the file object's SKIP_EMPTY
flag to not count empty lines in that file.
Richard Knop
I'm a software engineer mostly working on backend from 2011. I have used various languages but has been mostly been writing Go code since 2014. In addition, I have been involved in lot of infra work and have experience with various public cloud platforms, Kubernetes, Terraform etc. For databases I have used lot of Postgres and MySQL but also Redis and other key value or document databases. Check some of my open source projects: https://github.com/RichardKnop/machinery https://github.com/RichardKnop/go-oauth2-server https://github.com/RichardKnop
Updated on June 28, 2022Comments
-
Richard Knop almost 2 years
$file = new SplFileObject('/path/to/file.txt');
How can I find the number of lines in a file with
SplFileObject
? -
Richard Knop over 12 yearsI used fopen/fgets traditional way of reading files as you recommended, thanks. Sometimes I am just trying to do everything with classes when it's not needed.
-
Jan Dragsbaek over 12 yearsIf you want to do your filehandling in an object oriented way, thats exactly why SPL exists.
-
Typo over 10 yearsGreat answer but on larger file (10mb and 135,000+ lines in this case) it is entirely too slow and an attempt to count using this method actually results in a time out.
-
Twisted1919 over 10 yearsthis is wrong, seek() will look for line number while getSize() will return the filesize in bytes.
-
Николай Конев over 10 yearsI know. It just ensures that we seeked all file lines (even if all of them are empty). At most common cases, seek() will bump to EOF on line number that definitely less than bytes count, but PHP handles it silently, returning last line number. Agree, it is dirty hack, but i didn't found any "clean" way to count lines quickly.
-
Bala almost 7 yearsworks fine. But file has 99 lines but it returns 98. do you know why?
-
Simon about 3 yearsNOTE: key returns the index of the last line so this will always be one short of the total. You need to add one to the total:
$linesTotal = $file->key() + 1;