Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.042 c
4-1095947982
MakNik
2004-09-23 17:59
2004.10.31
Имя компьютера


1-1098176351
starik30
2004-10-19 12:59
2004.10.31
Обмен между потоками


1-1097817455
NewDelpher
2004-10-15 09:17
2004.10.31
Сообщения. Не знаю как подступиться.


1-1097591583
hooky-mars
2004-10-12 18:33
2004.10.31
Добавление строк в Excel


9-1088322595
Bizon's
2004-06-27 11:49
2004.10.31
Проекция точки





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский