|
|
|
| УСЛОВИЕ
есть большой файл (например на 1 000 000 строк), в каждой строке - нужная мне информация.
ЗАДАЧА
Как считать нужную строку (зная только номер), не считывая при этом весь файл? | |
|
|
|
|
|
|
|
для: SergijKa
(06.02.2006 в 18:19)
| | хммм
а чего это я все в виде задачи описал :))
я тут форум просмотрел - так это не задача, это просто проблемма у меня такая :) | |
|
|
|
|
|
|
|
для: SergijKa
(06.02.2006 в 18:57)
| | Не, так и надо задачи ставить.
А насчёт файла, то его по-любому сначала прочитать в переменную придётся.
Можно не весь, но до нужной строки точно. | |
|
|
|
|
|
|
|
для: Axxil
(06.02.2006 в 19:29)
| | значит, нету возможности без считывания всего файла получить решение типа "считать 78 358 строку файла"...
действительно, без считывания файла непонятно в чем именно брать это 78 358...
хорошо, другой вариант.
если я отдельно один раз сделаю перенос этого файла в массив, и потом просто буду его подключать вместо того чтобы подгружать файл и разбивать его - подгрузка этого массива будет идти быстрее чем подгрузка файла и перевод его в массив? | |
|
|
|
|
|
|
|
для: SergijKa
(06.02.2006 в 19:54)
| | да | |
|
|
|
|
|
|
|
для: Axxil
(06.02.2006 в 19:29)
| | приходим к такому вопросу: в каком виде лучше всего хранить информацию - файл, массив, или что?
информации этой ООЧЕНЬ МНОГО.
(базу данных использовать нельзя) | |
|
|
|
|
|
|
|
для: SergijKa
(06.02.2006 в 19:59)
| | Тут ситуация такая:
Файл это выражаясь компьютерным языком ПЗУ (постоянное запоминающее устройство)
массив это ОЗУ(оперативное запоминающие устройство). Т.е. все данные из массива будут утерен как только закончится выполнение скрипта. Поэтому хранить данные в массиве можно только во время исполнения программы.
Я не беру в расчёт механизм сессий так как вряд ли возможно передавать такие обьёмы посредством него.
В отсутствии базы данных можно попробовать механизм плоских файлов (точно не знаю что такое, но когда-то давно это здесь активно обсуждалось, можно найти в поиске)
Или индексировать данные самостоятельно, всё равно информация наверное структурирована и можно её разбить на логические разделы и хранить в отдельных файлах. | |
|
|
|
|
|
|
|
для: Axxil
(06.02.2006 в 21:45)
| | *Т.е. все данные из массива будут утерен как только закончится выполнение скрипта. Поэтому хранить данные в массиве можно только во время исполнения программы.*
я хочу делать require_once файл arr.php в котором будет идти инициализация массива типа
$all[] = "vasja";
$all[] = "petja";
$all[] = "kolja";
...
Этот файл я буду отдельно создавать, перед тем как в сеть скрипт вывешивать, из файла data.txt - там инфа вида
---
vasja
petja
kolja
---
Так вот, такой способ будет быстрее работать чем просто file("data.txt") ???
(Суть в том что этот файл никогда не меняется, но большущий очень)
*можно её разбить на логические разделы и хранить в отдельных файлах.*
вот от этого я и пытаюсь уйти.
не разбивать, но обрабатывать только один файл и при этом не загружать его полностью. | |
|
|
|
|
|
|
|
для: SergijKa
(06.02.2006 в 21:54)
| | Я нифига не понял что вы хотите сделать.
В любом случае данные надо инициализировать в программе... Прочитать, присвоить и т.д.
Да можно тупо весь милион строк загнать в массив присваиванием как у вас. То вряд ли ваш энтузиазм доживёт хотя бы до половины :)
Откуда такая привязанность к этому файлу?
Разбейте его хотя бы по алфавиту и грузите нужную часть...
А вообще желательно узнать как обрабатывается данный файл и что хотим получить на выходе | |
|
|
|
|
|
|
|
для: Axxil
(06.02.2006 в 22:02)
| | Разбейте его хотя бы по алфавиту и грузите нужную часть...
я сейчас так и делаю - разбиваю файл с миллионом значений на файлики по 100.
а потом по нужному номеру вычисляется нужный файлик и уже только он, маленький, обрабатывается.
но разбивка происходит очень долго.
а мне нужно разбивать такие файлики десятками.
вот я и хочу найти способ, с которым можно ничего не разбивать, но который бы дал возможность получить 127 225 699 строку без считывания всего огромного милионного файла.
так можно будет ничего не разбивать... и жить долго и счастливо :)
А вообще желательно узнать как обрабатывается данный файл и что хотим получить на выходе
а на выходе мы просто хотим по номеру 127 225 699 получить строку номер 127 225 699 . | |
|
|
|
|
|
|
|
для: SergijKa
(06.02.2006 в 22:16)
| | Надо изначально разбить файл и хранить его в виде кучи маленьких. Тогда и подключение и выбор новой строки не будет долгим | |
|
|
|
|
|
|
|
для: SergijKa
(06.02.2006 в 19:59)
| | Раз информации ОООЧЕНЬ много, то кроме как в файле (учитывая что БД применять нельзя) её хранить будет просто негде.
Можно предложить несколько вариантов, как ускорить медленный последовательный доступ к нужной записи.
Если строки, которые нужно хранить, имеют одинаковую длину, доступ можно сделать прямым. Умножаем длину строки на номер записи, позиционируемся прямо к ее началу.
Даже если у строк длина разная, но внешнее ограничение длины строк позволяет пренебречь потерями дискового пространства в угоду быстродействию (например в строках лежат имена, фамилии и т.п. сущности), будет вполне приемлемым записывать строки, дополняя их справа до одинакового размера заполнителями. И тогда, раз физическая длина стала одинаковой - см. предыдущий пункт.
Если размеры записей могут отличаться настолько, что максимальный размер не позволит терять пространство на заполнители (например, в строках лежат тела писем, статей, документов), можно предложить построить индекс (завести второй файл и записывать в нем позиции строк первого файла записями фиксорованного размера) и выкрутиться индексно-последовательным методом доступа. Впрочем, легко получится только если уже имеющиеся строки в ходе работы с таким хранилищем не модифицируются вообще либо модифицируются крайне редко. Новые могут добавляться свободно в конец. Но при изменении старых придется перезаписать весь основной файл и перестроить индекс от точки модификации.
Если модификацуия записей столь же частая операция, что и доступ к записям, придется применять более серьезные алгоритмические ухищрения, создавая того или иного рода деревья (B+, RB, AVL) т.е. структуры данных специально разработанные для хранения и доступа к данным. Другими словами, делать же на коленке СУБД, пусть даже простейшую.
Может всё же лучше попытаться избавиться от условия "базу данных использовать нельзя"?
Впрочем компромисс можно выбрать на любом шаге. | |
|
|
|
|
|
|
|
для: Trianon
(07.02.2006 в 10:44)
| | Вот я что-то не понимаю: а почему все надо хранить в одном файле? Можно же раздробить на много мелких и тогда задача сильно упроститься. | |
|
|
|
|
|
|
|
для: Loki
(07.02.2006 в 11:38)
| | Это называется перебросить тяжесть задачи доступа к данным с прикладного процесса на файловую систему. Иногда помогает. Не всегда. :)
По-моему, задача скорее усложнится. Вот сколько вопросов сразу начинает болеть в голове:
1. По какому критерию будем разбивать?
2. А не окажется ли так, что из, к примеру, сотни файлов, 5 будут пустыми , 92 почти пустыми, а оставшиеся три - размером порядка общего объема?
3. Как проверить что все файлы образуют единую целостную базу? А не разрозненный набор,
в котором часть файлов последней операцией изменили, а другую часть, увы, еще нет?
Или, допустим, как распознать ситуацию, когда при переносе таковой базы, какой-то из файлов потерялся/разрушился?
Даже с двумя файлами и то часть проблем всплывает.
Но они хотя бы решаются проще. А если не проще, то известными методами.
Целостность и свежесть индекса можно проверить.
Разрушенный индекс посчитать устаревшим.
Устаревший индекс перестроить заново.
А с одним файлом голова почти не болит.
То есть болит, но лишь за стоимость дискового пространства. | |
|
|
|
|
|
|
|
для: Trianon
(07.02.2006 в 12:17)
| | Ну для начала, это файнтазии что с моей стороны, что с вашей, так как реальной задачи нет, а есть только общий вопрос:)
Я бы, скорее всего, решал его так. А критерии - они от задачи зависеть будут. | |
|
|
|
|
|
|
|
для: Trianon
(07.02.2006 в 10:44)
| | Большое спасибо всем за помощь!
В моей ситуации больше всего подходит решение, которое предложил Trianon - отдельное ОООЧЕНЬ большое спасибо :)
Если размеры записей могут отличаться настолько, что максимальный размер не позволит терять пространство на заполнители (например, в строках лежат тела писем, статей, документов), можно предложить построить индекс (завести второй файл и записывать в нем позиции строк первого файла записями фиксорованного размера) и выкрутиться индексно-последовательным методом доступа. Впрочем, легко получится только если уже имеющиеся строки в ходе работы с таким хранилищем не модифицируются вообще либо модифицируются крайне редко. Новые могут добавляться свободно в конец. Но при изменении старых придется перезаписать весь основной файл и перестроить индекс от точки модификации.
Поскольку информация в огромном файле вообще не модифицируется, то я последую совету - сделаю отдельный файлик с позициями строк.
Еще раз большое всем спасибо. | |
|
|
|
|
|
|
|
для: SergijKa
(06.02.2006 в 18:19)
| | Можно построчно читать файл и счтитать стороки в файле
<?php
$handle = fopen ("/tmp/inputfile.txt", "r");
while (!feof ($handle)) {
$buffer = fgets($handle, 4096);
}
fclose ($handle);
?>
|
На каждой итерации цикла пременная $buffer будет содержать 1 строку файла. | |
|
|
|