Menu
Categories
[PHP] windows + line count
August 16, 2013 Сеть и интернет

Иногда может потребоваться узнать количество строк в файле. В Linux-системах для этих целей можно использовать утилиту wc, просто вызвав ее через exec:

$linecnt = exec("wc -l filename.txt");

А что делать, если PHP работает на компьютере под управлением Windows? В Windows-системах таковой утилиты напрочь нет. Рассмотрим возможные альтернативы:

1. Для небольших файлов, объем которых не превышает десятков килобайт, достаточно быстрым вариантом является загрузить все содержимое файла в память и посчитать количество получившихся строк:

$linecnt = count(file("filename.txt"));

Этот способ не подходит для больших файлов, т.к. таким образом можно легко зажевать всю доступную PHP память.

2. Для файлов чуть большего размера можно использовать циклический перебор строк и подсчитывать количество итераций до окончания файла:

$f = fopen("filename.txt",'r');
$linecnt = 0; while (fgets($f)) $linecnt++;
fclose($f);

Т.к. файл не загружается в память целиком, то расход памяти в данном подходе значительно меньше.

3. Для больших файлов можно использовать внешние средства. На просторах сети можно отыскать linux-утилиту wc, откомпилированную с Cygwin, и запустить ее в Windows. А можно обойтись и без установки стороннего софта – встречайте нецелевое использование стандартной утилиты find.exe (в сочетании с type.exe):

$linecnt = exec('type "filename.txt" | find /c /v ""');

При помощи type производится вывод на stdout содержимого файла, а find подсчитывает количество непустых строк. Необходимо обратить внимание, что утилита type вообще никаким образом не понимает относительных путей, поэтому для передачи пути к файлу не из текущего каталога необходимо воспользоваться функцией realpath().

Пример функции, позволяющий подсчитывать количество строк в крупных файлах как при запуске под Windows, так и под Linux:

function linecnt($path)
{
	if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
		return (int)exec('type "'.realpath($path).'" | find /c /v ""');
	else
		return (int)exec('wc -l '.$path);
}

PS: Интересная историческая справка о том, по какой причине find.exe может выискивать в файле непустые строки путем сравнения с “” (пустой строкой).

Leave a Reply




*