Форум: "Основная";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];
ВнизТекстовый файл огромного размера Найти похожие ветки
← →
ИМХО © (2004-10-16 20:39) [0]Гсопода, как работать с текстовым файлом огромного размера (>300 MB)? Понятно, что не при помощи TStringList.
← →
begin...end © (2004-10-16 20:41) [1]Наверное, это зависит от того, что ты с ним собираешься делать.
← →
ИМХО © (2004-10-16 20:55) [2]этот огромный файл - Unix mailbox (MBX)
нужно выцепить из него сообщения
← →
jack128 © (2004-10-16 21:10) [3]ИМХО © (16.10.04 20:55) [2]
Загружаешь в память, ну например, по 10 МБ файла - парсеришь на строки и ищешь, что те там надо. не нашел - грузишь следующие 10 МБ и так до победного конца.. Может можно как нить оптимизировать этот процесс, но нужны подробности.. формат этого файла..
← →
ИМХО © (2004-10-17 07:58) [4]еще идеи будут?
← →
Alx2 © (2004-10-17 08:16) [5]>ИМХО © (17.10.04 07:58) [4]
MMF - и все заботы на кэширование и оптимизацию доступа возьмет на себя операционка.
← →
default © (2004-10-17 08:16) [6][3] по-моему всё сказано
хочешь больше сам давай больше
← →
default © (2004-10-17 08:17) [7]только хотел про MFF сказать
это только если доступ последовательный
а так быстрей самому подгружать как надо
← →
ИМХО © (2004-10-17 11:06) [8]что за MMF (или MFF)?
где можно об этом почитать? (с примерами)
← →
VMcL © (2004-10-17 11:53) [9]>>ИМХО © (17.10.04 11:06) [8]
MMF - Memory Mapped File.
Почитать можно в Windows SDK, MSDN.
См. CreateFileMapping(), MapViewOfFile(), UnmapViewOfFile().
← →
ИМХО © (2004-10-17 12:14) [10]есть внятные примеры?
← →
Anatoly Podgoretsky © (2004-10-17 12:17) [11]ИМХО © (16.10.04 20:39)
Ну это же не огромный размер, а вполне обычный для логов, нормально считывается как в string так и в TStrings.
Я постоянно обрабатываю логи гораздо большего объема, с помощью обычного ReadLn, в зависимости от версии Дельфи надо учитывать разделители строк.
← →
ИМХО © (2004-10-17 12:20) [12]Толян, дык памяти никакой не хватит на гиговый текстовый файл!
← →
Anatoly Podgoretsky © (2004-10-17 12:24) [13]Это с ReadLn то, посмотри размер строк в ящиук, ты врядли увидишь свыше 80 байт, в крайнем случае несколько килобайт.
Другое дело если у тебя Д5-
← →
Verg © (2004-10-17 12:36) [14]Что-нибудь тапа этого
type
TMemFile = record
HFile, HMap : THandle;
Size : DWORD;
BaseAddress : pointer;
end;
procedure AllocMemFile(const F : string;var MemFile : TMemFile);
begin
FillChar(MemFile, sizeof(MemFile),0);
with MemFile do
begin
HFile:=CreateFile(pchar(F), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0,0);
if HFile<>INVALID_HANDLE_VALUE then
begin
Size:=GetFileSize(HFile, nil);
HMap:=CreateFileMapping(HFile, nil, PAGE_READONLY,0,0,nil);
if (HMap<>0) and (Size<>$FFFFFFFF) then
begin
BaseAddress:=MapViewOfFile(HMap,FILE_MAP_READ,0,0,0);
if BaseAddress=nil then
begin
CloseHandle(HMap);
CloseHandle(HFile);
HFile:=INVALID_HANDLE_VALUE;
HMap:=0;
end;
end else
begin
CloseHandle(HFile);
HFile:=INVALID_HANDLE_VALUE;
end;
end;
end;
end;
procedure FreeMemFile(var MemFile : TMemFile);
begin
with MemFile do
if (HFile<>INVALID_HANDLE_VALUE) and (BaseAddress<>nil) and (HMap<>0) then
begin
UnmapViewOfFile(BaseAddress);
CloseHandle(HMap);
CloseHandle(HFile);
FillChar(MemFile, sizeof(MemFile),0);
HFile:=INVALID_HANDLE_VALUE;
end;
end;
← →
ИМХО © (2004-10-17 13:14) [15]
> Anatoly Podgoretsky © (17.10.04 12:24) [13]
> Это с ReadLn то, посмотри размер строк в ящиук, ты врядли
> увидишь свыше 80 байт, в крайнем случае несколько килобайт.
> Другое дело если у тебя Д5-
Да, у меня Delphi 5. Как это меняет дело?
← →
ИМХО © (2004-10-17 14:43) [16]Еще такой вопрос по сабжу.
Вот у меня на компе 158 MB оперативки.
Это какого объема текстовый файл можно загрузить в TStringList?
← →
Sergey_Masloff (2004-10-17 14:55) [17]ИМХО © (17.10.04 14:43) [16]
>Еще такой вопрос по сабжу.
>Вот у меня на компе 158 MB оперативки.
Порядка 2 ГБ. Даже если оперативки 32 Мб. Или 16...
← →
VMcL © (2004-10-17 15:00) [18]>>Sergey_Masloff (17.10.04 14:55) [17]
>Порядка 2 ГБ. Даже если оперативки 32 Мб. Или 16...
Ну, наверное, не совсем так. Зависит от размера файла подкачки.
>>ИМХО © (17.10.04 14:43) [16]
См. [3]. Только лучше использовать буфер не фиксированного размера, а размером с какую-то часть от общего объема ОЗУ, например, 25% (можно вообще в программе настройку соответствующую сделать).
← →
ИМХО © (2004-10-17 15:28) [19]
> Sergey_Masloff (17.10.04 14:55) [17]
> Порядка 2 ГБ. Даже если оперативки 32 Мб. Или 16...
Изволите шутить, товарищ Маслофф? А как насчет Out of Memory?
← →
panov © (2004-10-17 15:28) [20]Зачем тебе в память закачивать весь файл или куски?
Чем тебя ReadLn не устраивает?
Приведи хотя бы одну причину, почему тебя советы использовать последовательную обработку файла не устраивают. Иначе остальное - пустая болтовня.
← →
ИМХО © (2004-10-17 15:30) [21]да, все правильно, меня ReadLn устроило. При первом открытии я узнал начальные позиции сообщений. Но как затем организовать быстрый доступ по индексу?
← →
ИМХО © (2004-10-17 15:32) [22]Seek не работает с текстовыми файлами!!!
← →
panov © (2004-10-17 15:33) [23]Для быстрой обработки больших объемов информации с произвольным доступом существуют СУБД.
Вывод очевиден - данные нужно закачивать в БД.
Второй вариант - писать свою систему управления БД, заточенную именно на эти данные.
← →
panov © (2004-10-17 15:34) [24]>ИМХО © (17.10.04 15:30) [21]
Но как затем организовать быстрый доступ по индексу?
А индекс где будешь хранить?
← →
panov © (2004-10-17 15:35) [25]Кстати, 300Мб - не очень большой объем логов.
У меня обрабатываются журналы размером около 2Гб.
← →
ИМХО © (2004-10-17 15:36) [26]сорри, СУБД отпадает. Решение должно быть проще.
Как теперь вытащить из текстового файла строки, скажем, с 2111570 по 2111710?
← →
ИМХО © (2004-10-17 15:38) [27]300 метров - это самое малое, что есть.
← →
VMcL © (2004-10-17 15:39) [28]>>ИМХО © (17.10.04 15:36) [26]
Строки фиксированной длины?
← →
panov © (2004-10-17 15:40) [29]>ИМХО © (17.10.04 15:36) [26]
В таком случае работа с файлом, как с текстовым, не подходит.
Существует такой выход:
1. Проход по файлу как по текстовому с вычислением смещений начала и конца каждой строки относительно начала файла.
2. Формирование дополнительного файла с индексами(по существу, это и будет своеобразный индексный файл).
3. Далее работаем с файлом как с файлом произвольного доступа.
Любую строку теперь можно получить по ее индексу, вычисляя смещение относительно начала файла.
← →
ИМХО © (2004-10-17 16:01) [30]
> VMcL © (17.10.04 15:39) [28]
> >>ИМХО © (17.10.04 15:36) [26]
>
> Строки фиксированной длины?
к сожалению, нет :(
← →
ИМХО © (2004-10-17 16:02) [31]
> panov © (17.10.04 15:40) [29]
> В таком случае работа с файлом, как с текстовым, не подходит.
>
> Существует такой выход:
черт меня подери, а ведь это ИДЕЯ! Сенкс!
← →
ИМХО © (2004-10-17 16:29) [32]что-то я тут тормознулся...
как осуществить это:
> Проход по файлу как по текстовому с вычислением смещений
> начала и конца каждой строки относительно начала файла.
?
я думал, что это просто (считывай Readln(F, S) и складывай Length(S)), а это не так
← →
Sergey_Masloff (2004-10-17 16:59) [33]ИМХО © (17.10.04 15:28) [19]
>Изволите шутить, товарищ Маслофф? А как насчет Out of Memory?
Тамбовский волк... ;-)
Что там с оут оф мемори? Родственник ваш оут оф мемори? Дядя он Вам?
До ~2 Гб в TStringList влезет при любом объеме оперативки достаточном для работе ОС. Естественно ОС будет расширять файл подкачки и если его макс. размер ограничен то нехватка памяти случится раньше.
Сейчас за 2 минуты написал тестовый пример и спокойно поместил в стринглист 1.7 Гб файл. Всего памяти в системе 256 Мб файл подкачки до примера 360 Мб после 1940 Мб.
← →
Palladin © (2004-10-17 17:03) [34]позвольте с вами категорично не согласится
естественно ОС не будет расширять его если он зафиксирован, как например сделано у меня для предотвращения его фрагментации
← →
Sergey_Masloff (2004-10-17 17:07) [35]А чего не соглашаться. Если зафиксирован то естественно - у меня так и написано.
Ваши личные настройки на общие принципы ну никак не влияют ;-) Кстати все равно все это баловство. В реальной работе абсолютно не заметно влияние фрагментации этой ;-)
← →
Anatoly Podgoretsky © (2004-10-17 17:14) [36]ИМХО © (17.10.04 13:14) [15]
Сушественно меняет, для Д5 это будет одна строка, поскольку он ен обрабатывает ограничители в формате Юник, Д6 и выше это делает. Значит тебе придется читать блоками и самому разбивать на строки и элементы. Жругой вариант перейти на Д6+
Тогда обработка будет выглядеть весьма просто и занимать минимум ресурсов.while not Eof(F) do begin
ReadLn(F, {f1, f2, ...} S);
...
end;
← →
Palladin © (2004-10-17 17:20) [37]
> [35] Sergey_Masloff (17.10.04 17:07)
точно... не заметил оговорки :)
а по поводу фрагметации... это не заметно на NTFS... но в win9x очень заметно... лучше сразу ограничить оптимизировать NU и тада будет счасте... иначе жуткое обращение к диску обеспечено... он расширит, а сузить забудет :)
← →
Sergey_Masloff (2004-10-17 17:24) [38]Palladin © (17.10.04 17:20) [37]
>но в win9x очень заметно...
Понятно. Я и не знал.
← →
panov © (2004-10-17 17:32) [39]>ИМХО © (17.10.04 16:29) [32]
думал, что это просто (считывай Readln(F, S) и складывай Length(S)), а это не так
Ну, возможно, надо прибавить к длине каждой строки 2 (если строки заканчиваются #13#10)
← →
ИМХО © (2004-10-17 18:22) [40]
> panov © (17.10.04 17:32) [39]
> Ну, возможно, надо прибавить к длине каждой строки 2 (если
> строки заканчиваются #13#10)
и здесь вы оказались абсолютно правы, спасибо.
а вот такой вопрос можно?
как теперь лучше обращаться к файлу:
1) через TFileStream.Create, затем Position и Read
или
2) через AssignFile, Reset(FromF, 1), Seek и BlockRead
???
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.06 c