Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> чтение только одной строки из большого файла 
V
    Опции темы
Antarn
Дата 13.8.2007, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 11.8.2006

Репутация: нет
Всего: нет



Здравствуйте.

Имеется текстовой файл с записями следующего типа:

текст|еще текст
другой текст|текст
еще текст|текст
 
и т.д.
файл считывается в массив с помощью функции file(), и потом рендомно работается с одной строкой - записью массива.

но сам файл весит 7,5мб и имеет более 150 000 записей.

можно ли считывать сразу только одну строку из файла ? (положение строки рендомное).
PM MAIL   Вверх
z-END
Дата 13.8.2007, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 5
Всего: 102



fopen, fgets, fseek
но конечно изврат... по хорошему тут только БД поможет =)


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Severyanin
Дата 13.8.2007, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
**


Профиль
Группа: Участник
Сообщений: 554
Регистрация: 31.7.2007
Где: Россия, Омск

Репутация: нет
Всего: 9



А зачем тогда считывать весь файл? Может, ипользовать fgets с рандомным смещением относительно начала файла?


--------------------
"Звонким вереском скроются наши следы, и не вспомнят о них. Кто поверит нам, рыцарям павшей звезды из отвергнутых книг? Пусть в узоре времен ни стихов. ни имен, но напомнит забывшим их полуночный крик." Тэм Гринхилл
"Ужели суслик твоего коварства нагадит в плов доверья моего?". Л.Филатов 
PM MAIL WWW ICQ   Вверх
Antarn
Дата 13.8.2007, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 11.8.2006

Репутация: нет
Всего: нет



БД использовать пока нет возможности.

а вот то, что можно делать смещение в fgets  я не знал. спасибо smile попробуем так smile
PM MAIL   Вверх
Severyanin
Дата 13.8.2007, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
**


Профиль
Группа: Участник
Сообщений: 554
Регистрация: 31.7.2007
Где: Россия, Омск

Репутация: нет
Всего: 9



Ну не совсем в fgets smile .  Сначала задать смещение, а затем - вызвать fgets smile 


--------------------
"Звонким вереском скроются наши следы, и не вспомнят о них. Кто поверит нам, рыцарям павшей звезды из отвергнутых книг? Пусть в узоре времен ни стихов. ни имен, но напомнит забывшим их полуночный крик." Тэм Гринхилл
"Ужели суслик твоего коварства нагадит в плов доверья моего?". Л.Филатов 
PM MAIL WWW ICQ   Вверх
xamloru
Дата 13.8.2007, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 35
Регистрация: 2.8.2007

Репутация: нет
Всего: нет



только скорее всего после fseek ты попадешь на центр какой нибудь строки, поэтому запускай 2-а раза fgets, и все будет ОК, кроме первой и последней строки в файле!
PM MAIL   Вверх
Antarn
Дата 13.8.2007, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 11.8.2006

Репутация: нет
Всего: нет



Цитата

Ну не совсем в fgets smile .  Сначала задать смещение, а затем - вызвать fgets smile  

ну я понел. fseek-ом задаем смещение, потом юзаем fgets  smile 

Цитата

только скорее всего после fseek ты попадешь на центр какой нибудь строки, поэтому запускай 2-а раза fgets, и все будет ОК, кроме первой и последней строки в файле!

спасибо за идею smile не споткнусь здесь.


PM MAIL   Вверх
Mal Hack
Дата 13.8.2007, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 122
Всего: 261



При fopen файл все равно помещается в память целиком. Читаете вы его или нет.
Работа с большими файлами должна вестись через потоки. Сам не реализовывал, не было необходимости, но именно в таком случае можно считывать только то, что надо.

fseek - о хорошему, вообще для бинарных файлов с четкой структурой. Для строковых ее лучше не использовать...
Знаю, сейчас некоторые тут начнут умничать "ну ведь работает же"... В ПХП много чего работает, даже скрипт с неинициалиированной переменной...

Это сообщение отредактировал(а) Mal Hack - 13.8.2007, 13:24
PM ICQ   Вверх
Diesel Draft
Дата 13.8.2007, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 876
Регистрация: 18.1.2005
Где: Lviv, Ukraine

Репутация: 1
Всего: 5



Цитата(Mal Hack)

При fopen файл все равно помещается в память целиком. Читаете вы его или нет.


Вот ты подумал что сказал? Про поточи слышал? Знаешь что такое? fopen открывает не поток?


--------------------
НЕДОМА в маси 
PM MAIL WWW ICQ GTalk   Вверх
Mal Hack
Дата 13.8.2007, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 122
Всего: 261



Diesel Draft, свой хамский тон уйми, пожалуйста. ;)

Цитата(Diesel Draft @  13.8.2007,  15:03 Найти цитируемый пост)
Вот ты подумал что сказал? Про поточи слышал? Знаешь что такое? fopen открывает не поток? 

Тот факт, что фопен помещает файл целиком в память - 100%.
Поток-то потоком, но надо отличать низкоуровневые от высокоуровневых потоков..
фопен ищет файл, затем полностью его преписывает в память, после чего возвращает указатель на стартовую ячейку памяти, да при этом, по сути, устанавливается, отчасти, потоковое соединение, но я имел ввиду несколько другой механизм, когда файл не помещается целиком в память, а лишь ссылка на его местоположение на диске, и уже низкоуровневыми потоками идет обращение к нужному сегменту файла.

Я очень сильно сомневаюсь, что разработчки в фопен реализовали схему, т.к. на Си фопен 100% работает так, как описано в первом случае, да и тема тут была годичной давности, когда у кого-то из пользователей была проблема использования памяти с большим по объему файлом.
PM ICQ   Вверх
Diesel Draft
Дата 13.8.2007, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 876
Регистрация: 18.1.2005
Где: Lviv, Ukraine

Репутация: 1
Всего: 5



Цитата

Diesel Draft, свой хамский тон уйми, пожалуйста. ;)

та я там смайл поставить забыл  smile 

Вот ты здесь и не прав. Я помню когда появился РНР5 то в многих статях писало что теперь РНР будет поддерживать потоки, которые раньше только емулирувались.  
Можно проверить. У меня на роботе нет РНР интерпретатора. Поэтому если у тебя есть то помоги парню.
Просто загрузи припустим песню и посмотри на сколько изменились затраты памяти. 


--------------------
НЕДОМА в маси 
PM MAIL WWW ICQ GTalk   Вверх
sTa1kEr
Дата 13.8.2007, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 56
Всего: 146



Цитата(Mal Hack @  13.8.2007,  13:23 Найти цитируемый пост)
При fopen файл все равно помещается в память целиком. Читаете вы его или нет.

Цитата(Mal Hack @  13.8.2007,  15:20 Найти цитируемый пост)
Тот факт, что фопен помещает файл целиком в память - 100%.
Поток-то потоком, но надо отличать низкоуровневые от высокоуровневых потоков..
фопен ищет файл, затем полностью его преписывает в память, после чего возвращает указатель на стартовую ячейку памяти, да при этом, по сути, устанавливается, отчасти, потоковое соединение, но я имел ввиду несколько другой механизм, когда файл не помещается целиком в память, а лишь ссылка на его местоположение на диске, и уже низкоуровневыми потоками идет обращение к нужному сегменту файла.

Это не так. Да, fopen() не использует прямой доступ к файлу и не может позиционировать курсор в произвольное место файла, но он никогда не читает сразу весь файл в память. В PHP, конечно, можно позиционировать курсор, но методика несколько иная. При смещении курсора на $offset байт ему приходится прочитать эти $offset байт (что бы прочитать 1кб из середины файла размера 100мб, придется прочитать ~50мб). Т.о. fopen() практически не расходует память, но при использовании fseek() будет загружать винт.
Для работы с прямым доступом к диску можно использовать функции Direct IO Functions

Цитата(Mal Hack @  13.8.2007,  13:23 Найти цитируемый пост)
fseek - о хорошему, вообще для бинарных файлов с четкой структурой.

Совершенно согласен, по хорошему fseek() вообще не должен работать в ASCII режиме. И если нету на то особой причины, то лучше всегда читать в бинарном режиме.

PM MAIL   Вверх
Oflashp
Дата 13.8.2007, 21:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 2.8.2007
Где: Россия, Санкт-Пет ербург

Репутация: 1
Всего: 2



Код

<?
$file = "some.txt";
$fp = fopen($file, r);
$fr = fread($fp, "1024");
$fr_array = explode("\n", $fr);
if(count($fr_array)>1)
{
echo $fr_array[0]; //Вывести первую строку. Соответственно $fr_array[n] массив со строками, где (n+1) = номер строки.
}
?>

PM MAIL ICQ   Вверх
Antarn
Дата 13.8.2007, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 11.8.2006

Репутация: нет
Всего: нет



спасибо всем отписавшимся.

Mal Hack, можно дать линк с простейшим примером использования потоков при работе с файлами ?


Oflashp, спасибо за старание, но в вашем примере в массив опять-таки записывается весь файл. а требуется доступ к случайной строке, не считывая весь файл.
PM MAIL   Вверх
Mal Hack
Дата 13.8.2007, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 122
Всего: 261



Цитата(Diesel Draft @  13.8.2007,  15:24 Найти цитируемый пост)
Я помню когда появился РНР5 то в многих статях писало что теперь РНР будет поддерживать потоки, которые раньше только емулирувались.  

Хм... Что-то я такого не помню, подкинь ссылку, посмотрю.

Цитата(sTa1kEr @  13.8.2007,  18:51 Найти цитируемый пост)
Да, fopen() не использует прямой доступ к файлу и не может позиционировать курсор в произвольное место файла, но он никогда не читает сразу весь файл в память. В PHP, конечно, можно позиционировать курсор, но методика несколько иная. 

Если только в 5 это поменяли... Раньше такого точно не могло быть. 100%. Тестировал я большие файлы... Точно помню на 4 было так, как в сях.

Цитата(sTa1kEr @  13.8.2007,  18:51 Найти цитируемый пост)
При смещении курсора на $offset байт ему приходится прочитать эти $offset байт (что бы прочитать 1кб из середины файла размера 100мб, придется прочитать ~50мб). Т

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

Antarn, sTa1kEr дал ссылку на DIO функции.

Вообще, надо бы протестировать. Я к сожалению не имею под рукой рабочего сервера и не могу этого сделать...
Вообще, с точки зрения здравой логики, фопен и смежные функции должны быть как в сях, т.к. в принципе работа с большими файлами - редка, а с маленькими лучше работать в оперативе. А для больших файлов есть DIO, как было указано выше.
PM ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1134 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.