Эффективно считая количество строк текстового файла. (200mb +) - PullRequest
80 голосов
/ 29 января 2010

Я только что узнал, что мой скрипт выдает мне фатальную ошибку:

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 440 bytes) in C:\process_txt.php on line 109

Эта строка такова:

$lines = count(file($path)) - 1;

Так что я думаю, что ему трудно загрузить файл в память и подсчитать количество строк, есть ли более эффективный способ сделать это без проблем с памятью?

Текстовые файлы, которые мне нужны для подсчета количества строк в диапазоне от 2 МБ до 500 МБ. Может быть, концерт иногда.

Спасибо всем за любую помощь.

Ответы [ 16 ]

0 голосов
/ 26 октября 2017

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

$lines = count(file('your.file'));
echo $lines;
0 голосов
/ 23 декабря 2016

Основано на решении Доминик Роджера, вот что я использую (он использует wc, если он доступен, в противном случае возможен отказ от решения доминирующего Роджера)

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;
    }
}

https://github.com/lingtalfi/Bat/blob/master/FileTool.php

0 голосов
/ 19 февраля 2015

Для подсчета строк используйте:

$handle = fopen("file","r");
static $b = 0;
while($a = fgets($handle)) {
    $b++;
}
echo $b;
0 голосов
/ 29 августа 2014
public function quickAndDirtyLineCounter()
{
    echo "<table>";
    $folders = ['C:\wamp\www\qa\abcfolder\',
    ];
    foreach ($folders as $folder) {
        $files = scandir($folder);
        foreach ($files as $file) {
            if($file == '.' || $file == '..' || !file_exists($folder.'\\'.$file)){
                continue;
            }
                $handle = fopen($folder.'/'.$file, "r");
                $linecount = 0;
                while(!feof($handle)){
                    if(is_bool($handle)){break;}
                    $line = fgets($handle);
                    $linecount++;
                  }
                fclose($handle);
                echo "<tr><td>" . $folder . "</td><td>" . $file . "</td><td>" . $linecount . "</td></tr>";
            }
        }
        echo "</table>";
}
0 голосов
/ 03 августа 2014

Есть еще один ответ, который, я подумал, может быть хорошим дополнением к этому списку.

Если у вас установлено perl и вы можете запускать вещи из оболочки в PHP:

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

Это должно обрабатывать большинство разрывов строк из файлов, созданных Unix или Windows.

ДВА недостатка (как минимум):

1) Не очень хорошая идея, чтобы ваш скрипт зависел от системы, в которой он работает (возможно, небезопасно предполагать, что Perl и wc доступны)

2) Просто небольшая ошибка при выходе, и вы передали доступ к оболочке на вашем компьютере.

Как и большинство вещей, которые я знаю (или думаю, что знаю) о кодировании, я получил эту информацию откуда-то еще:

Джон Рив Артикул

0 голосов
/ 29 января 2010

У вас есть несколько вариантов. Первый - увеличить доступную доступную память, что, вероятно, не лучший способ сделать что-либо, учитывая, что вы заявляете, что файл может стать очень большим. Другой способ - использовать fgets для построчного чтения файла и увеличения счетчика, что вообще не должно вызывать проблем с памятью, поскольку в текущий момент времени в памяти находится только текущая строка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...