Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: как прочитать только нужную строку не скачивая весь файл
 
 автор: SergijKa   (06.02.2006 в 18:19)   письмо автору
 
 

УСЛОВИЕ
есть большой файл (например на 1 000 000 строк), в каждой строке - нужная мне информация.

ЗАДАЧА
Как считать нужную строку (зная только номер), не считывая при этом весь файл?

   
 
 автор: SergijKa   (06.02.2006 в 18:57)   письмо автору
 
   для: SergijKa   (06.02.2006 в 18:19)
 

хммм
а чего это я все в виде задачи описал :))
я тут форум просмотрел - так это не задача, это просто проблемма у меня такая :)

   
 
 автор: Axxil   (06.02.2006 в 19:29)   письмо автору
 
   для: SergijKa   (06.02.2006 в 18:57)
 

Не, так и надо задачи ставить.
А насчёт файла, то его по-любому сначала прочитать в переменную придётся.
Можно не весь, но до нужной строки точно.

   
 
 автор: SergijKa   (06.02.2006 в 19:54)   письмо автору
 
   для: Axxil   (06.02.2006 в 19:29)
 

значит, нету возможности без считывания всего файла получить решение типа "считать 78 358 строку файла"...
действительно, без считывания файла непонятно в чем именно брать это 78 358...

хорошо, другой вариант.

если я отдельно один раз сделаю перенос этого файла в массив, и потом просто буду его подключать вместо того чтобы подгружать файл и разбивать его - подгрузка этого массива будет идти быстрее чем подгрузка файла и перевод его в массив?

   
 
 автор: 1999   (06.02.2006 в 19:58)   письмо автору
 
   для: SergijKa   (06.02.2006 в 19:54)
 

да

   
 
 автор: SergijKa   (06.02.2006 в 19:59)   письмо автору
 
   для: Axxil   (06.02.2006 в 19:29)
 

приходим к такому вопросу: в каком виде лучше всего хранить информацию - файл, массив, или что?

информации этой ООЧЕНЬ МНОГО.

(базу данных использовать нельзя)

   
 
 автор: Axxil   (06.02.2006 в 21:45)   письмо автору
 
   для: SergijKa   (06.02.2006 в 19:59)
 

Тут ситуация такая:
Файл это выражаясь компьютерным языком ПЗУ (постоянное запоминающее устройство)
массив это ОЗУ(оперативное запоминающие устройство). Т.е. все данные из массива будут утерен как только закончится выполнение скрипта. Поэтому хранить данные в массиве можно только во время исполнения программы.
Я не беру в расчёт механизм сессий так как вряд ли возможно передавать такие обьёмы посредством него.
В отсутствии базы данных можно попробовать механизм плоских файлов (точно не знаю что такое, но когда-то давно это здесь активно обсуждалось, можно найти в поиске)
Или индексировать данные самостоятельно, всё равно информация наверное структурирована и можно её разбить на логические разделы и хранить в отдельных файлах.

   
 
 автор: SergijKa   (06.02.2006 в 21:54)   письмо автору
 
   для: Axxil   (06.02.2006 в 21:45)
 

*Т.е. все данные из массива будут утерен как только закончится выполнение скрипта. Поэтому хранить данные в массиве можно только во время исполнения программы.*

я хочу делать require_once файл arr.php в котором будет идти инициализация массива типа
$all[] = "vasja";
$all[] = "petja";
$all[] = "kolja";
...

Этот файл я буду отдельно создавать, перед тем как в сеть скрипт вывешивать, из файла data.txt - там инфа вида
---
vasja
petja
kolja
---

Так вот, такой способ будет быстрее работать чем просто file("data.txt") ???
(Суть в том что этот файл никогда не меняется, но большущий очень)

*можно её разбить на логические разделы и хранить в отдельных файлах.*
вот от этого я и пытаюсь уйти.
не разбивать, но обрабатывать только один файл и при этом не загружать его полностью.

   
 
 автор: Axxil   (06.02.2006 в 22:02)   письмо автору
 
   для: SergijKa   (06.02.2006 в 21:54)
 

Я нифига не понял что вы хотите сделать.
В любом случае данные надо инициализировать в программе... Прочитать, присвоить и т.д.
Да можно тупо весь милион строк загнать в массив присваиванием как у вас. То вряд ли ваш энтузиазм доживёт хотя бы до половины :)
Откуда такая привязанность к этому файлу?
Разбейте его хотя бы по алфавиту и грузите нужную часть...
А вообще желательно узнать как обрабатывается данный файл и что хотим получить на выходе

   
 
 автор: SergijKa   (06.02.2006 в 22:16)   письмо автору
 
   для: Axxil   (06.02.2006 в 22:02)
 

Разбейте его хотя бы по алфавиту и грузите нужную часть...

я сейчас так и делаю - разбиваю файл с миллионом значений на файлики по 100.
а потом по нужному номеру вычисляется нужный файлик и уже только он, маленький, обрабатывается.

но разбивка происходит очень долго.

а мне нужно разбивать такие файлики десятками.

вот я и хочу найти способ, с которым можно ничего не разбивать, но который бы дал возможность получить 127 225 699 строку без считывания всего огромного милионного файла.

так можно будет ничего не разбивать... и жить долго и счастливо :)

А вообще желательно узнать как обрабатывается данный файл и что хотим получить на выходе
а на выходе мы просто хотим по номеру 127 225 699 получить строку номер 127 225 699 .

   
 
 автор: Axxil   (07.02.2006 в 09:11)   письмо автору
 
   для: SergijKa   (06.02.2006 в 22:16)
 

Надо изначально разбить файл и хранить его в виде кучи маленьких. Тогда и подключение и выбор новой строки не будет долгим

   
 
 автор: Trianon   (07.02.2006 в 10:44)   письмо автору
 
   для: SergijKa   (06.02.2006 в 19:59)
 

Раз информации ОООЧЕНЬ много, то кроме как в файле (учитывая что БД применять нельзя) её хранить будет просто негде.

Можно предложить несколько вариантов, как ускорить медленный последовательный доступ к нужной записи.

Если строки, которые нужно хранить, имеют одинаковую длину, доступ можно сделать прямым. Умножаем длину строки на номер записи, позиционируемся прямо к ее началу.

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

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

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

Может всё же лучше попытаться избавиться от условия "базу данных использовать нельзя"?
Впрочем компромисс можно выбрать на любом шаге.

   
 
 автор: Loki   (07.02.2006 в 11:38)   письмо автору
 
   для: Trianon   (07.02.2006 в 10:44)
 

Вот я что-то не понимаю: а почему все надо хранить в одном файле? Можно же раздробить на много мелких и тогда задача сильно упроститься.

   
 
 автор: Trianon   (07.02.2006 в 12:17)   письмо автору
 
   для: Loki   (07.02.2006 в 11:38)
 

Это называется перебросить тяжесть задачи доступа к данным с прикладного процесса на файловую систему. Иногда помогает. Не всегда. :)

По-моему, задача скорее усложнится. Вот сколько вопросов сразу начинает болеть в голове:
1. По какому критерию будем разбивать?
2. А не окажется ли так, что из, к примеру, сотни файлов, 5 будут пустыми , 92 почти пустыми, а оставшиеся три - размером порядка общего объема?
3. Как проверить что все файлы образуют единую целостную базу? А не разрозненный набор,
в котором часть файлов последней операцией изменили, а другую часть, увы, еще нет?
Или, допустим, как распознать ситуацию, когда при переносе таковой базы, какой-то из файлов потерялся/разрушился?

Даже с двумя файлами и то часть проблем всплывает.
Но они хотя бы решаются проще. А если не проще, то известными методами.
Целостность и свежесть индекса можно проверить.
Разрушенный индекс посчитать устаревшим.
Устаревший индекс перестроить заново.

А с одним файлом голова почти не болит.
То есть болит, но лишь за стоимость дискового пространства.

   
 
 автор: Loki   (07.02.2006 в 14:11)   письмо автору
 
   для: Trianon   (07.02.2006 в 12:17)
 

Ну для начала, это файнтазии что с моей стороны, что с вашей, так как реальной задачи нет, а есть только общий вопрос:)
Я бы, скорее всего, решал его так. А критерии - они от задачи зависеть будут.

   
 
 автор: SergijKa   (07.02.2006 в 15:37)   письмо автору
 
   для: Trianon   (07.02.2006 в 10:44)
 

Большое спасибо всем за помощь!
В моей ситуации больше всего подходит решение, которое предложил Trianon - отдельное ОООЧЕНЬ большое спасибо :)

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

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

Еще раз большое всем спасибо.

   
 
 автор: cheops   (07.02.2006 в 03:28)   письмо автору
 
   для: SergijKa   (06.02.2006 в 18:19)
 

Можно построчно читать файл и счтитать стороки в файле
<?php
$handle 
fopen ("/tmp/inputfile.txt""r");
while (!
feof ($handle)) {
    
$buffer fgets($handle4096);
}
fclose ($handle);
?> 

На каждой итерации цикла пременная $buffer будет содержать 1 строку файла.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования