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

Вниз

маппинг файлов   Найти похожие ветки 

 
Arm79 ©   (2007-06-06 16:58) [0]

Здравствуйте. Сейчас пишу анализатор логовых файлов, решил использовать маппинг файлов. Явных проблем не было, но смущает большое время доступа к маппированным данным.
Пробовал открыть файл размером 100 мегов.

Таким кодом создаю маппинг, использую случай wmReadShare
procedure TCustomMappedFile.Open;
 var
   FileMode: Integer;
   PageMode: Integer;
   MapMode : Integer;
begin
  case FWorkMode of
    wmWrite:
      begin
        FileMode := fmOpenReadWrite;
        PageMode := PAGE_READWRITE;
        MapMode  := FILE_MAP_ALL_ACCESS;
      end;
    wmReadShare:
      begin
        FileMode := fmOpenRead + fmShareDenyNone;
        PageMode := PAGE_READONLY;
        MapMode  := FILE_MAP_READ;
      end;
    wmWriteShare:
      begin
        FileMode := fmOpenReadWrite + fmShareDenyNone;
        PageMode := PAGE_READWRITE;
        MapMode  := FILE_MAP_ALL_ACCESS;
      end;
  else
      begin
        FileMode := fmOpenRead;
        PageMode := PAGE_READONLY;
        MapMode  := FILE_MAP_READ;
      end;
  end;

  iFileHandle := FileOpen(FFileName, FileMode);
  if iFileHandle >= 0
  then begin
    FFileSize  := FileSeek(iFileHandle, 0, 2);
    iMapHandle := CreateFileMapping(iFileHandle, nil, PageMode, 0, 0, nil);
    if iMapHandle > 0
    then begin
      FDataPtr := MapViewOfFile(iMapHandle, MapMode, 0, 0, 0);
    end;
  end;

  if (iFileHandle < 0) or (iMapHandle <=0) or not Assigned(FDataPtr)
  then begin
    GetErrorMessage;

    try
      if iMapHandle > 0
      then CloseHandle(iMapHandle);
    except
    end;

    try
      if iFileHandle >=0
      then FileClose(iFileHandle);
    except
    end;

    iFileHandle := 0;
    iMapHandle  := 0;
    FDataPtr    := nil;

    RaiseError;
  end;
end;


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

function TCustomLogReader.IsNodeExists(var Ptr: PAnsiChar; KeyWord: string; var Node: string): boolean;
 var
   BeginStr, EndStr: string;
   pcTemp          : PAnsiChar;
begin
 Result    := False;
 Node      := EmptyStr;

 BeginStr  := "<@" + KeyWord;
 EndStr    := KeyWord + "@>";

 pcTemp    := StrPos(Ptr, PAnsiChar(BeginStr));
 if Assigned(pcTemp)
 then begin
   Inc(pcTemp, Length(BeginStr));
   Ptr     := pcTemp;
   pcTemp  := StrPos(pcTemp, PAnsiChar(EndStr));
   if Assigned(pcTemp)
   then begin
     SetString(Node, Ptr, Integer(pcTemp) - Integer(Ptr));
     Inc(pcTemp, Length(EndStr));
     Ptr   := pcTemp;
     Result:= True;
   end;
 end;
end;


Может я изначально неправильно что то использую? В чем могут быть траблы? Или так и должно быть? Я, например, часто пользуюсь viewer-ом от Total Commander, он файлы такого размера влет открывает, и ищет в них текст гораздо шустрее


 
Leonid Troyanovsky ©   (2007-06-06 21:19) [1]


> Arm79 ©   (06.06.07 16:58)  

> Может я изначально неправильно что то использую?

Изначально непонятно, как оное планировалось использовать.
Если требуется произвольный доступ, то неясно, почему StrPos,
а не, скажем, разбор всего файла.
Если доступ последовательный, а StrPos лишь для примера, то неясно,
что хотелось от filemapping.

--
Regards, LVT.


 
Arm79 ©   (2007-06-07 14:18) [2]

Файл имеет структуру:

<@entry
 ...
entry@>

<@entry
 ...
entry@>

<@entry
 ...
entry@>

и т.д.

Он может быть большого размера, до 500-600 Мбайт, поэтому я решил попробовать использовать FileMapping

Алгоритм работы следующий:
Получить указатель на данные, затем в цикле (ПОКА НАХОДИТСЯ пара <@entry entry@> производить анализ данных между ними, и перемещаться далее

 
   pcTemp := DataPtr;
   while IsNodeExists(pcTemp, "entry", sNode)
   do begin
     if Assigned(FonNode)
     then FOnNode(Self,
                        Value(sNode, "datetime"),
                        Value(sNode, "category"),
                        Value(sNode, "place"),
                        Value(sNode, "text"));
   end;


 
MBo ©   (2007-06-07 14:20) [3]

пара <@entry entry@> может находиться на разных строках?


 
Arm79 ©   (2007-06-07 14:22) [4]

она и находится на разных строках )))

вот пример из файла:

<@entry
 <@datetime 09:09:39:213 datetime@>
 <@category Информация category@>
 <@place TfrmMain.Create place@>
 <@text Началась ротация логов... text@>
entry@>

<@entry
 <@datetime 09:09:39:229 datetime@>
 <@category Информация category@>
 <@place TfrmMain.Create place@>
 <@text Окончание ротации логов text@>
entry@>

<@entry
 <@datetime 09:09:39:229 datetime@>
 <@category Информация category@>
 <@place TfrmMain.aFileGetBrokersExecute place@>
 <@text Включена работа через ADO text@>
entry@>

<@entry
 <@datetime 09:57:51:305 datetime@>
 <@category Информация category@>
 <@place TfrmMain.aFileGetBrokersExecute place@>
 <@text Начало соединения... text@>
entry@>


 
MBo ©   (2007-06-07 14:29) [5]

Похоже, что достаточно жесткий формат, тогда проще построчно читать.
По строке <@entry переходим в состояние " читаем данные"
Если в состоянии "читаем данные" встретили строку entry@> (или конец файла, если это возможно) -  обрабатываем блок и переходим в состояние " ждем нового блока"


 
Arm79 ©   (2007-06-07 14:32) [6]

То есть я так понял вы рекомендуете отказаться от FileMapping и использовать обычный ReadLn?

Наверное я так и сделаю, но ведь хотелось бы разобраться почему через FileMapping не получается...


 
MBo ©   (2007-06-07 14:40) [7]

>То есть я так понял вы рекомендуете отказаться от FileMapping и использовать обычный ReadLn

Не обязательно, можно  с маппингом построчно читать - искать символы перевода строки. Не исключено, что можно в пару раз скорость чтения поднять по сравнению с Readln, но если разбор данных ведется заметно дольше чтения- то смысла особого нет.


 
Arm79 ©   (2007-06-07 14:53) [8]


> MBo ©   (07.06.07 14:40) [7]
> >То есть я так понял вы рекомендуете отказаться от FileMapping
> и использовать обычный ReadLn
>
> Не обязательно, можно  с маппингом построчно читать - искать
> символы перевода строки. Не исключено, что можно в пару
> раз скорость чтения поднять по сравнению с Readln, но если
> разбор данных ведется заметно дольше чтения- то смысла особого
> нет.

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

банальный StrPos в самый первый поиск целую минуту думает.
Сейчас буду пробовать самому написать поиск подстроки


 
homm ©   (2007-06-07 15:01) [9]

> банальный StrPos в самый первый поиск целую минуту думает.

Во время думания обращается к жесткому диску?


 
MBo ©   (2007-06-07 15:02) [10]

>банальный StrPos
так не надо им пользоваться

чтение одной строки:

function TMMFTextRead.ReadLine: string;
var
 i: integer;
begin
 i := 0;
 PMap := @PBegin[FPosition];
 while (FPosition + i < FSize) and (PMap[i] <> 13) do
   Inc(i);
 SetString(Result, PChar(PMap), i);
 Inc(FPosition, i + 2);
end;


PBegin - PByteArray


 
Deka ©   (2007-06-07 15:12) [11]

Возможно надо оптимизировать код функции StrPos конкретно для Вашего применения ...


 
Arm79 ©   (2007-06-07 15:40) [12]


> homm ©   (07.06.07 15:01) [9]
> > банальный StrPos в самый первый поиск целую минуту думает.
>  
>
> Во время думания обращается к жесткому диску?


Грузит процессор со страшной силой


> Deka ©   (07.06.07 15:12) [11]
> Возможно надо оптимизировать код функции StrPos конкретно
> для Вашего применения ...


Думаю, что слегка переделанный вариант MBo ©   (07.06.07 15:02) [10]  (отдельное спасибо за участие) и и есть там самая оптимизация функции


 
Anatoly Podgoretsky ©   (2007-06-07 19:36) [13]

При чтение с помощью ReadLn вообще никакой Pos не требуется и размер файла не ограничен.


 
Arm79 ©   (2007-06-09 16:59) [14]


> Anatoly Podgoretsky ©   (07.06.07 19:36) [13]
> При чтение с помощью ReadLn вообще никакой Pos не требуется
> и размер файла не ограничен.

Я в курсе )). Просто хочу потренироваться в этой области.



Страницы: 1 вся ветка

Текущий архив: 2007.08.19;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.015 c
15-1184921014
Kolan
2007-07-20 12:43
2007.08.19
Однако не появления BDS2006 на TaskBar е сильно виляет на работу.


15-1185167960
ZMRaven
2007-07-23 09:19
2007.08.19
А сколько может стоить курсач на дельфях?


5-1160128745
Alek_1
2006-10-06 13:59
2007.08.19
idSMTP


2-1185404147
Альберт
2007-07-26 02:55
2007.08.19
и еще об окне поверх остальных


2-1185178959
ambhtr
2007-07-23 12:22
2007.08.19
Как из интернета скопировать таблицу