Эффективно считая количество строк текстового файла. (200 МБ +)

Вы можете использовать проверку уникальности с опцией scope.

Кроме того, вы должны добавить уникальный индекс в БД, чтобы предотвратить повторную проверку новых записей при проверке в то же время перед записью:

class AddUniqueIndexToReleases < ActiveRecord::Migration
  def change
    add_index :releases, [:country, :medium], unique: true
  end
end



class Release < ActiveRecord::Base
  validates :country, uniqueness: { scope: :medium }
end

80
задан Abs 29 January 2010 в 14:26
поделиться

4 ответа

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

$file="largefile.txt";
$linecount = 0;
$handle = fopen($file, "r");
while(!feof($handle)){
  $line = fgets($handle);
  $linecount++;
}

fclose($handle);

echo $linecount;

FGES загружает одну строку в память (если второй аргумент $ Длина опущена, он будет читать от потока, пока он не достигнет конца линии, который мы хотим). Это все еще вряд ли будет так быстро, как и использование чего-либо, кроме PHP, если вы заботитесь о времени стены, а также использование памяти.

Единственная опасность с этим, если какие-либо строки особенно долго (что, если вы столкнулись с файлом 2 ГБ без разрывов строки?). В этом случае вам лучше высказать его в куски, и считая концерты в конечном итоге:

$file="largefile.txt";
$linecount = 0;
$handle = fopen($file, "r");
while(!feof($handle)){
  $line = fgets($handle, 4096);
  $linecount = $linecount + substr_count($line, PHP_EOL);
}

fclose($handle);

echo $linecount;
152
ответ дан 24 November 2019 в 09:21
поделиться

Самое сжатое межплатформенное решение, которое только буферизует одну строку за один раз.

$file = new \SplFileObject(__FILE__);
$file->setFlags($file::READ_AHEAD);
$lines = iterator_count($file);

, К сожалению, мы должны установить эти READ_AHEAD флаг иначе iterator_count блоки неограниченно долго. Иначе это было бы остротой.

0
ответ дан 24 November 2019 в 09:21
поделиться

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

0
ответ дан 24 November 2019 в 09:21
поделиться

setInterval () является пока только универсальным решением. Но в будущем есть свет в виде события hashchange

-121--796507-

Используйте

Request.Form []

для переменных POST,

Request.QuireString []

для GET.

-121--1187348-

Если это выполняется на хосте Linux/Unix, самым простым решением будет использование exec () или аналогичного для выполнения команды wc -l $ path . Просто убедитесь, что вы санировали $ path сначала, чтобы убедиться, что это не что-то вроде "/path/to/file; rm -rf/. "

34
ответ дан 24 November 2019 в 09:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: