Reputation: 3990
To determine the exact number of lines in a file I currently use:
if(exec("wc -l ".escapeshellarg($strFile), $arResult)) {
$arNum = explode(" ", $arResult[0]);
// ...
}
What is the best way of doing the same on Windows?
Edit:
One attempt from another question:
$file="largefile.txt";
$linecount = 0;
$handle = fopen($file, "r");
while(!feof($handle)){
$line = fgets($handle);
$linecount++;
}
fclose($handle);
echo $linecount;
Has anyone got experience with this way using big files?
Is there a way of using Windows commands to determine file size other then PHP functions?
Solution
I go with command find
as recommended by the accepted answer in the comments.
Upvotes: 2
Views: 2622
Reputation: 141
This is using substr_count
and is much faster than fgets
:
$file="largefile.txt";
$linecount = 0;
$chunk_size = (2<<20); // 2MB chuncks
$handle = fopen($file, "r");
while(!feof($handle)){
$chunk = fread($handle,$chunk_size);
$linecount += substr_count($chunk,PHP_EOL);
// $linecount += substr_count($chunk,"\n"); // also with \n, \r, or \r\n
}
fclose($handle);
echo $linecount;
The code is taking into consideration the use of least memory (2 MB chunks).
Benchmark with a 85 MB file and 8M+ lines, execution time is:
• fgets
: 52.11271 sec.
• substr_count(PHP_EOL)
: 0.58844 sec.
• substr_count(\n)
: 0.353772 sec.
• find /c /v "" largefile.txt
: 100 sec.
However, if one have no problem with the memory available on the host system, like the OP, and proper memory limit in PHP is set (larger than the file length), substr_count
can search the entire content of file with much performance:
$file="largefile.txt";
@ini_set('memory_limit', (2<<24)+(filesize($file)) ); // 32 MB for PHP + File size
$linecount = 0;
$handle = file_get_contents($file);
if($handle) $linecount = substr_count($handle, PHP_EOL);
echo $linecount;
You may choose whatever memory size you want for the interpreter.
Benchmark: 0.46878 sec.
Upvotes: 0
Reputation: 146460
Windows command to calculate line numbers:
find /c /v "" < type file-name.txt
Adapted from Stupid command-line trick: Counting the number of lines in stdin.
Upvotes: 0
Reputation: 4455
I prefer to just loop through the file, reading a line each time and incrementing a counter, using and counting the array returned by file() is only good for smaller files.
<?php
$loc = 'Ubuntu - 10.10 i386.iso';
$f = fopen($loc,'r');
$count = 0;
while (fgets($f)) $count++;
fclose($f);
print "Our file has $count lines" . PHP_EOL;
if you'd use file() for a such a large file it would read it completely into memory, which can be prohibitive depending on your situation. If this is a 1-time "I don't care, it's my workstation and I have enough memory" situation or the files are guaranteed to be small then you could use
count(file($loc));
Otherwise I'd loop through, especially since if action would have to be performed by many processes. Both ways of counting loop through the whole of the file but memory increases vastly in the second case.
Upvotes: 0
Reputation: 24815
Perhaps you could use:
$length = count(file($filename));
Which would work everywhere.
file()
reads the file into an array, split on newlines, and count()
counts the length of an array.
If it doesn't work properly (at macintosh files for example), take a look here: http://www.php.net/manual/en/filesystem.configuration.php#ini.auto-detect-line-endings
Upvotes: 3