Есть список недействительных паспортов - файл в 1.5 Гб и есть задачка проверять по этому списку клиентов. Но на сервере оперативки всего 2 гига. То есть, через file_get_contents его не открыть. Какие тут есть варианты, кроме как парсить его на мощном компе на тысячи срок и записывать построчно в базу MySQL, которую потом переносить на сервер?
кусочек за кусочком в цикле складываешь в буфер. из буфера читаешь номер, сравниваешь, пока буфет не станет такой маленький, что номера паспорта в нем не помещается читаешь следующую порцию данных, доклеиваешь в буфер и снова отрезаешь номер, сравниваешь и т.п.
Эм... это ничего не даст. Файл представляет из себя набор паспортных данных, которые идут построчно и поля разделены запятыми. Если fread разобьёт строку посередине серии паспорта например, то сверка с серией клиента не пройдёт. Вот был бы способ читать файл построчно... --- Добавлено --- Хотяяя... можно сохранять с предыдущим куском, склеивать с ним и проверять. То есть, получаем кусок 2, склеиваем с куском 1, получается разрыв между этими кусками убрали. Далее получаем кусок 3, склеиваем с куском 2, проверяем - разрыв между 2 и 3 тоже убрали. И так далее. Вроде правильная логика... Получается, каждый кусок будет проверяться по 2 раза, но зато без разрывов. Интересно даст ли это что-то в принципе, может скрипт так и съест 1.5 гига оперативки в процессе прогона цикла. Точнее, уже 3 гига, потому что я там собрался дублировать куски по 2 раза.
К чему извращения? Загнал в мускульной и радуйся. Ели ж хочется прям извращений - прочел строку в буфер, сравнил, очистил буфер и так в цикле. Памяти мало съест, но скорость будет не ахти
@Nerfed ты понимаешь, что на разовую проверку одного пасспорта придется прочесть и сравнить число со всеми данными в пасспорте? и так каждый раз пихай в бд, читая по-кусочкам. когда файл с новыми данными приходит - в бд его. а запросы уже все к бд.
PHP: $fileHandler = fopen($file, "r"); while($line = fgets($fileHandler)){ list($columnA, $columnB) = explode(",", $line); // magic goes here } fclose($fileHandler);
Еще недавно использовал такой классный трюк, когда надо читать большими кусками, но чтобы делилось построчно. Т.е. как бы "округлять" по строчкам. В твоем случае хорошо подойдет, потому что читать 1.5Гбайт построчно - долговато. Лучше читать кусками. Код (Text): //тут размер куска $size = 4096; $bigfile = 'bigfile.txt'; $h = fopen($bigfile, 'r'); do { $str = fread($h, $size) . fgets($h); //читаем заданный размер + 1 строку } while (!feof($h));
fopen выгружает файл в оперативку полностью же? Для построчного разбора есть ещё готовая функция: https://php.ru/manual/function.file.html Короче сделали по алгоритму, который я описывал выше. Работает шустро, сервер не греет. Такой скрипт идеально подойдёт, если в файле в принципе ничего не разбито на строки, а сравнить как-то надо. PHP: $size_open_file = 5000; $filesize = filesize($path); if ($filesize <= $size_open_file) { $size_open_file = $filesize; } $handle = fopen($path, "r"); $flag_search = 0; $contents_prev = ""; do { $contents = fread($handle, $size_open_file); $contents_prev = $contents; if (substr_count($contents_prev.$contents, $search_number)) { $flag_search = 1; break; } $filesize = $filesize - $size_open_file; } while ($filesize >= 0); fclose($handle); --- Добавлено --- Нам этот файл надо будет обновлять раз в неделю. Качать к себе, парсить в базу, заливать новую базу на сервер = слишком много телодвижений. А так, просто залил новый файл на сервер и доволен. Потом ещё сделаем автоматическое скачивание файла на сервер по ссылке раз в сутки. Для этого надо будет раздуплить как разархивировать 1.5 гиговый файл из архива gz2 и не уронить при этом сервер.
Ты ничего не понял из тех дельных советов, что тебе надовали тут. Ты хоть каждый каждый день бд обновляй, это все равно проще и эффективнее будет, чем по файлу проверять. Извини за прямоту. Твой код, мягко говоря, избыточен. Ты сам понимаешь полностью каждую строчку? Наверняка к моей писанине тоже можно ещё круче доебаться, но тут я не могу не сказать. Индусам платят за кодинг построчно, вот они так как у тебя пишут. $filesize = filesize()
Вы видимо путаете что-то с file_get_contents. fopen создаёт поток из файла, управляют которым fread, fwite, fgets...
Нет, просто предоставляет "указатель на файл", посредством которого другие функции (fread, fgets) выполняют над этим файлом свою работу... И ещё в приведённом в сообщении 12 коде надо 11-ю строчку перенести за 15-ю.