PHP - случайная строка из большого файла (500мб) - Форум успешных вебмастеров - GoFuckBiz.com - Страница 2
 
 
Форум успешных вебмастеров - GoFuckBiz.com

  Форум успешных вебмастеров - GoFuckBiz.com > Бизнес-решения > Скрипты, программы и технические решения
Дата
USD/RUB90.2486
BTC/USD69003.3677
Скрипты, программы и технические решения Обсуждаем скрипты, программы и новые технологии.

Закрытая тема
Опции темы Опции просмотра
Старый 17.11.2011, 13:33
Start Post: PHP - случайная строка из большого файла (500мб) 
  #11
Ower
ё
 
Аватар для Ower
 
Регистрация: 26.10.2011
Сообщений: 1,520
Бабло: $311895
По умолчанию

Использовать для файла в 500мб и 15кк строками функции file() и file_get_contents() - верх извращения.

Нужно какое то другое решение. Уже естественно нагуглил несколько, но у меня во всех случаях выдается пустая строка. В общем вот сорц

PHP код:
$h fopen("text.txt",'r');
$counter 0;

while (!
feof($h)) {
    
fgets($h);
    
$counter++;
}
rewind($h);

$line rand(0$counter);

$counter 0;
while (!
feof($h)) {
    if (
$counter == $line) {echo fgets($h);}
    
$counter++;
}
fclose($h); 
Сперва формируется кол-во строк, далее делаем случайные выборки. Суть в том, что у меня переменная $counter не считается, ну т.е. не увеличивается. Почему - я так и не понял. Попробовал заменить в файле \n на \r\n, не помогло. Попробовал еще несколько аналогичных вариантов, все равно не работает. Хелп
Ower вне форума  
Старый 17.11.2011, 15:58   #12
Ower
ё
 
Аватар для Ower
 
Регистрация: 26.10.2011
Сообщений: 1,520
Бабло: $311895
ТС -->
автор темы ТС По умолчанию

Цитата:
Сообщение от t0os Посмотреть сообщение
А эту задачу точно нельзя решить ни на чем, кроме PHP?
я не кодер, кроме php ничего не знаю
Ower вне форума  
Старый 17.11.2011, 16:04   #13
chesser
автоматизирую интернеты
 
Аватар для chesser
 
Регистрация: 05.07.2009
Адрес: chesser.ru
Сообщений: 3,362
Бабло: $470735
По умолчанию

Цитата:
Сообщение от t0os Посмотреть сообщение
А эту задачу точно нельзя решить ни на чем, кроме PHP?
а на чем ее решать лучше?
тут вроде и так все элементарно, где php будет лажать?

на баше возможно быстрее выйдет, он как-то поближе к системным ресурсам:
Код:
[user@server ~]$ cat file.txt | sort -R
__________________
USA и NL серверы и VPS | wiki | блог | Drupal | NginxТДС
Ave, Google, morituri te salutant! © chesser
chesser вне форума  
Старый 17.11.2011, 16:13   #14
sergeospb
коплю на феррари
 
Регистрация: 03.07.2008
Сообщений: 1,251
Бабло: $148195
По умолчанию

Цитата:
Сообщение от Ower Посмотреть сообщение
Оптимизация штука конечно полезная, но я не привык таким заниматься - работает и ладно))
Правда сейчас вот немного оптимизировал процесс выборок - Во первых разбил исходный файл на 1000 более мелких файлов, а во вторых сделаю из каждого файла по 10 выборок (Т.е. циклов перебора файлов теперь в 10 раз меньше, потому что в них еще есть 10 под-циклов).
Короче сделал то, что и хотел - быстрые выборки
Выдает - int(22)
гм. а в файле говоришь сколько строк на самом деле?
sergeospb вне форума  
Старый 17.11.2011, 16:51   #15
Ower
ё
 
Аватар для Ower
 
Регистрация: 26.10.2011
Сообщений: 1,520
Бабло: $311895
ТС -->
автор темы ТС По умолчанию

Цитата:
Сообщение от sergeospb Посмотреть сообщение
гм. а в файле говоришь сколько строк на самом деле?
15кк примерно
Ower вне форума  
Старый 17.11.2011, 17:51   #16
BOOLEAN
Member
 
Регистрация: 15.11.2010
Сообщений: 56
Бабло: $16940
По умолчанию

//Что то типо такого)
PHP код:
//Функция чтения нужного количества строк из файла
//Тип резалта аррай или строка 0 строка, 1 аррай
function get_file_lines($filename$count_line$rezdel=""$type=0)
{
    if(
$count_line == 0) return false;
    
$h fopen($filename"rb");

//Количество строк
    
while (!feof($h)) { 
         
fgets($h); 
         
$counter++; 
    } 
    
    
rewind($h);
//рандомная строка
    
$line mt_rand(0$counter-$count_line); 

    
        while(!
feof($h) && $line--) {
        
fgets($h);
       }
//нужное количество
        
while(!feof($h)){
             
$fbuffer[] = fgets($h);
             
$count_line--;
             if(
$count_line == 0) break;
             }
        
fclose($h);

//тип    
        
if($type)
        {
            return 
$fbuffer;
        }
$out_str implode($rezdel$fbuffer);
return 
$out_str;


Последний раз редактировалось BOOLEAN; 17.11.2011 в 18:00.
BOOLEAN вне форума  
Старый 17.11.2011, 18:56   #17
digg
$400
 
Аватар для digg
 
Регистрация: 17.05.2009
Сообщений: 14,040
Бабло: $1904870
Отправить сообщение для digg с помощью ICQ
По умолчанию

в коде
while (!feof($h)) {
if ($counter == $line) {echo fgets($h);}
$counter++;
}
эта хрень не переходит без fgets по строкам
fgets нужно каждый раз делать
digg вне форума  
Старый 18.11.2011, 15:35   #18
vilnus
Member
 
Регистрация: 12.02.2010
Сообщений: 41
Бабло: $7055
По умолчанию

На самом деле все просто:

PHP код:
$file 'file.txt';
$fp fopen($file,'r');
fseek($fp,rand(0,filesize($file)));
fgets($fp);
if(
feof($fp)) fseek($fp,0);
$str fgets($fp
Комментарии:

Открываем файл, переходим на произвольное место в нем.
Скорее всего это место окажется где-нибудь в середине строки.
Вряд ли нам так повезет, что мы сразу попадем куда надо.
Поэтому дальше мы через fgets() читаем оставшийся кусок до \n, а потом уже читаем строку.
Это и будет случайная строка файла.

Последний раз редактировалось vilnus; 18.11.2011 в 15:42.
vilnus вне форума  
Старый 18.11.2011, 17:21   #19
GoodLife
Show Me the Money
 
Аватар для GoodLife
 
Регистрация: 13.11.2009
Сообщений: 78
Бабло: $14079
По умолчанию

vilnus
совершенный код
Offtopic
GoodLife вне форума  
Старый 18.11.2011, 18:51   #20
digg
$400
 
Аватар для digg
 
Регистрация: 17.05.2009
Сообщений: 14,040
Бабло: $1904870
Отправить сообщение для digg с помощью ICQ
По умолчанию

бля, точно fseek
но, помню у меня были в свое время какие-то заморочки давным давно с ним
не помню какие точно, но помню ебался прилично
digg вне форума  
Старый 18.11.2011, 20:30   #21
Drg
Senior Member
 
Регистрация: 19.09.2009
Сообщений: 4,096
Бабло: $611825
По умолчанию

Цитата:
Сообщение от vilnus Посмотреть сообщение
На самом деле все просто:

PHP код:
$file 'file.txt';
$fp fopen($file,'r');
fseek($fp,rand(0,filesize($file)));
fgets($fp);
if(
feof($fp)) fseek($fp,0);
$str fgets($fp
Комментарии:

Открываем файл, переходим на произвольное место в нем.
Скорее всего это место окажется где-нибудь в середине строки.
Вряд ли нам так повезет, что мы сразу попадем куда надо.
Поэтому дальше мы через fgets() читаем оставшийся кусок до \n, а потом уже читаем строку.
Это и будет случайная строка файла.
Эх) как раз что-то подобное и использовал одно время) fseek реально помогает, но все равно тормоза, да и винт жалко, постоянно насилуется.
Потом я придумал решение сделать из 500 мг, например 10 гиг, способом описанным выше, а уже эти 10 гиг разбить на кучу маленьких файлов и обращаться за раз только к одному, как раз тогда степень случайности повышается)
Drg вне форума  
Закрытая тема