Случайная строка из большого файла

Статус
В этой теме нельзя размещать новые ответы.

w666w

Guest
Случайная строка из большого файла

Нужно БЫСТРО и без загрузки ресурсов прочитать случайную строку из БОЛЬШОГО файла. Читать весь файл в массив получается нерационально, fgets в принципе подходит, но как тогда передвинуть указатель на начало случ. строки? В общем какие соображения будут в этом направлении?
 

SelenIT

IT-лунатик :)
Как вариант: [m]fseek[/m] к случайному месту файла + [m]fread[/m] 2*(наибольшая возможная длина строки) байт + вырезать полную строку ([m]substr[/m]+[m]strpos[/m]/[m]strrpos[/m] или регуляркой).
 

w666w

Guest
Хороший вариант, не подумал.
Вопрос теоретический - такой метод чтения fseek + fgets*2 будет ли реально быстрее и экономичней с точки зрения ресурсов чем чтение всего файла в массив и rand выборка из этого массива?
 

digs

Новичок
Сделать еще один файлик (бинарный), в котором будут храниться "смещение" + "длина строки" для каждой строки в большом файле. Его читаешь (он получится маленький), потом берешь случайную пару и по ней читаешь строку из боьшого файла
 

SiMM

Новичок
> Как вариант: fseek к случайному месту файла + fread 2*(наибольшая возможная длина строки) байт
Только в этом случае вероятность выборки конкретной строки будет зависеть как минимум от её длины.
 

antson

Новичок
Партнер клуба
w666w
Еще как вариант сделать файл с фиксированным размером строки.
СлучайноеЧисло в диапазоне от 0 до РазмерФайла/РазмерСтроки
fseek ( РазмерСтроки * СлучайноеЧисло)
 

Фанат

oncle terrible
Команда форума
Вопрос теоретический - такой метод чтения fseek + fgets*2 будет ли реально быстрее и экономичней с точки зрения ресурсов чем чтение всего файла в массив и rand выборка из этого массива?
а ты сам-то как думаешь, теоретик?
 

ForJest

- свежая кровь
w666w
Ты не указал, какие тебе именно ресурсы нужно экономить - что для тебя важнее:
- Память
- Процессорное время
- Количество позиционирований головки винчестера
- Время работы программиста
- <нужное вписать>
 

fizot

Новичок
Вот то, что тебе нужно!!!

$fp = fopen($file, "r");
fseek($fp, rand(0, filesize($file)) );
fgets($fp);
echo "<B>".fgets($fp)."</b>";
fclose($fp);
 

SiMM

Новичок
fizot, и что мы получим, если fseek будет выполнен на последний байт в файле? Диггер, блин.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
тут 2 варианта ускорения:
или индексирование длин строк (в памяти, базе, файле),
или (если количество строк предсказуемо, а предсказуемость выборки допустима) - последовательное считывание строк, сохранение позиций строк в массиве, сравнение mt_rand с константой и возврат последней считанной строки при совпадении, а если совпадения не было - array_rand по массиву с позициями+fseek к нужной
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху