• Функция fgets()
работает до тех пор, пока объем текстовых файлов не превысит 20 МБ, а скорость синтаксического анализа значительно снизится.
• Функция file_ get_contents()
дает хорошие результаты до 40 МБ и приемлемые результаты до 100 МБ, но file_get_contents()
загружает весь файл в память , поэтому он не масштабируется.
• Функция file()
губительна для больших текстовых файлов, поскольку эта функция создает массив, содержащий каждую строку текста, поэтому этот массив сохраняется в памяти, а используемая память еще больше.
На самом деле, файл размером 200 МБ, который мне удалось обработать только с memory_limit
, установленным на 2 ГБ, что было неприемлемо для файлов размером более 1 ГБ, которые я собирался проанализировать.
Когда вам нужно проанализировать файлы размером более 1 ГБ, а время анализа превысило 15 секунд, и вы хотите избежать загрузки всего файла в память, вам нужно найти другой способ.
Мое решение состояло в том, чтобы проанализировать данные в произвольных маленьких кусках . Код:
$filesize = get_file_size($file);
$fp = @fopen($file, "r");
$chunk_size = (1<<24); // 16MB arbitrary
$position = 0;
// if handle $fp to file was created, go ahead
if ($fp) {
while(!feof($fp)){
// move pointer to $position in file
fseek($fp, $position);
// take a slice of $chunk_size bytes
$chunk = fread($fp,$chunk_size);
// searching the end of last full text line
$last_lf_pos = strrpos($chunk, "\n");
// $buffer will contain full lines of text
// starting from $position to $last_lf_pos
$buffer = mb_substr($chunk,0,$last_lf_pos);
////////////////////////////////////////////////////
//// ... DO SOMETHING WITH THIS BUFFER HERE ... ////
////////////////////////////////////////////////////
// Move $position
$position += $last_lf_pos;
// if remaining is less than $chunk_size, make $chunk_size equal remaining
if(($position+$chunk_size) > $filesize) $chunk_size = $filesize-$position;
$buffer = NULL;
}
fclose($fp);
}
Используется только память $chunk_size
, а скорость немного меньше, чем у file_ get_contents()
. Я думаю, что PHP Group должна использовать мой подход для оптимизации своих функций синтаксического анализа.
*) Найти функцию get_file_size()
здесь .