2

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;
  1. Has anyone got experience with this way using big files?

  2. 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.

Shlomo
  • 3,880
  • 8
  • 50
  • 82

4 Answers4

3

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

Rene Pot
  • 24,681
  • 7
  • 68
  • 92
0

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.

Harald Brinkhof
  • 4,375
  • 1
  • 22
  • 32
  • you realize you could just keep using wc -l via cygwin right? :) – Harald Brinkhof Jun 21 '12 at 09:28
  • I do not have control over server environment. – Shlomo Jun 21 '12 at 09:33
  • could you run a batch script /DOS command via shell_exec/exec? like `find /V /C "&!@Not_Existing&!@" my_file.text` the chance that that string is in a file of yours should be small :) – Harald Brinkhof Jun 21 '12 at 09:37
  • Thanks! My code: `if(exec('find /V /C "&!@Not_Existing&!@" '. escapeshellarg($strFile), $arResult)) { $arResult[0]; } else { // ... try fopen() }` I have no clue what `find` returns! Is the line number `$arResult` or `$arResult[0]`? Got no Windows here. – Shlomo Jun 21 '12 at 10:05
  • me neither but it seems to be the 2nd parameter (http://www.robvanderwoude.com/find.php ) just do a print_r and find out. :) – Harald Brinkhof Jun 21 '12 at 10:40
  • Im gonna accept your answer since you were the first coming up with `find`. Thanks. – Shlomo Jun 22 '12 at 07:50
0

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.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
0

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.

Tinel Barb
  • 121
  • 1
  • 4