Как взять часть файла?

Задача стоит следующая. Есть файл примерно окало 50-70тс строк, строки разной длины.
Нужно взять случайную строку из файла, но при этом сам файл не загружать в поток. так как его размер 150метров. а нужна одна случайная строка.

Были попытки передвигать внутренний указатель файла на количество байт.
Но так как строка разная, то может возятся 2 строки куском.

Чет я прегрустнул, в голову вообще не чего не лезет. Может кто знает или сталкивался?
  • Вопрос задан
  • 3925 просмотров
Пригласить эксперта
Ответы на вопрос 9
avalak
@avalak
Если нельзя загнать данные в базу, то могу предложить велосипед-костыль. Можно построить индекс (файл с парами смещение: длина, данные выровнять) и использовать его для доступа к строкам.
Ответ написан
Речь идет про програмный метод? Если да, то можно взять случайный указатель где-то внутри файла и потом найти ближайший "\n" (или какой там указатель конца строки), а потом взять кусок от этого до следующего указателя конца строки (или конца файла если это вдруг последняя строчка).
Ответ написан
Комментировать
deadkrolik
@deadkrolik
filesize + fseek + снова fseek на N влево пока не найдем перевод строки + fread
Ответ написан
Комментировать
lesha_firs
@lesha_firs Автор вопроса
ну да программный :) я брал указатель. но как найти "\n"? не загружая файл?
Ответ написан
strib
@strib
Ответ написан
Комментировать
EndUser
@EndUser
«Случайная строка» это случайная от слова random() или от слова «произвольно задуманная с номером N»?
Если второе, то создать индекс файла.
Ответ написан
Arris
@Arris
Сапиенсы учатся, играя.
А не вариант построить индекс по файлу? Типа «номер строки» — «смещение». Съэмулировать СУБД, так сказать?
Ответ написан
AHTOH
@AHTOH
Я бы определил максимально возможную длину строки и в произвольном месте (fseek) читал бы двойную длину (fread). И потом уже в полученном фрагменте искал бы строку, ограниченную двумя переводами строки или даже sscanf'ом.
Ответ написан
Комментировать
DmZ
@DmZ
А зачем что-то искать если родные функции PHP отлично все найдут за вас.
Делаете fseek в случайное место файла. Делаете первый fgets() или stream_get_line() c достаточным размером буфера — они гарантированно сами найдут конец строки. Далее делаете fseek от первоначального места + считанная длина строки — т.е. гарантированно попадаете на начало след. строки, которой делаете fgets() и используете.
(Нужно добавить проверки на EOF конечно)
Таким образом вы получите свою строку ценой памяти занятой буфером fgets/stream_get_line и все.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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