У меня есть файл размером 1,2 ГБ, содержащий строку с одной строкой. Мне нужно искать весь файл, чтобы найти позицию другой строки (в настоящее время у меня есть список строк для поиска). То, как я делаю это сейчас, – это открыть большой файл и переместить указатель через блоки 4Kb, а затем переместить указатели X в файл и получить еще 4Kb.
Моя проблема в том, что большая строка для поиска, больше времени, которое он принимает, чтобы получить ее.
Можете ли вы дать мне несколько идей по оптимизации сценария, чтобы улучшить время поиска?
это моя реализация:
function busca($inici){ $limit = 4096; $big_one = fopen('big_one.txt','r'); $options = fopen('options.txt','r'); while(!feof($options)){ $search = trim(fgets($options)); $retro = strlen($search);//maybe setting this position absolute? (like 12 or 15) $punter = 0; while(!feof($big_one)){ $ara = fgets($big_one,$limit); $pos = strpos($ara,$search); $ok_pos = $pos + $punter; if($pos !== false){ echo "$pos - $punter - $search : $ok_pos <br>"; break; } $punter += $limit - $retro; fseek($big_one,$punter); } fseek($big_one,0); } }
Заранее спасибо!
Почему бы не использовать exec
+ grep -b
?
exec('grep "new" ext-all-debug.js -b', $result); // here we have looked for "new" substring entries in the extjs debug src file var_dump($result);
результат выборки:
array(1142) { [0]=> string(97) "3398: * insert new elements. Revisiting the example above, we could utilize templating this time:" [1]=> string(54) "3910:var tpl = new Ext.DomHelper.createTemplate(html);" ... }
Каждый элемент состоит из смещения строки в байтах от начала файла и самой строки, разделенной двоеточием.
Поэтому после этого вы должны заглянуть внутрь конкретной линии и добавить позицию к смещению линии. То есть:
[0]=> string(97) "3398: * insert new elements. Revisiting the example above, we could utilize templating this time:"
это означает, что «новое» появление найдено на 3408-м байте (3398 – позиция линии, а 10 – позиция «нового» внутри этой линии)
$big_one = fopen('big_one.txt','r'); $options = fopen('options.txt','r'); while(!feof($options)) { $option = trim(fgets($options)); $position = substr($big_one,$option); if($position) return $position; //exit loop }
в$big_one = fopen('big_one.txt','r'); $options = fopen('options.txt','r'); while(!feof($options)) { $option = trim(fgets($options)); $position = substr($big_one,$option); if($position) return $position; //exit loop }
однако размер файла довольно большой. вы можете захотеть вместо этого сохранить данные в базе данных. или если вы абсолютно не можете, используйте grep-решение, размещенное здесь.