Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.31;
Скачать: CL | DM;

Вниз

Текстовый файл огромного размера   Найти похожие ветки 

 
ИМХО ©   (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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.027 c
11-1082007349
nester
2004-04-15 09:35
2004.10.31
Как создать поток без MCK?


14-1096458489
VMcL
2004-09-29 15:48
2004.10.31
Acoustic Mania


1-1097836813
Артем К.
2004-10-15 14:40
2004.10.31
Как из своего компонента отследить


1-1097683247
Mihail
2004-10-13 20:00
2004.10.31
как присоеденить скаченый компонент, поместить его на палитру ?


14-1097137128
Игорь Шевченко
2004-10-07 12:18
2004.10.31
Вопрос к бывшим владельцам старого железа