Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.06.2008, 14:29   #1
Vlad_3310
 
Регистрация: 16.06.2008
Сообщений: 5
По умолчанию Алгоритм поиска HEX строки в файле

Помогите пожалуста оптимизировать алгоритм поиска HEX строки в файле, а то уж больно долгий он у меня, или посоветуйте другой способ.

Код:
  type
    SBMTable = array[0..255] of byte;

  type
    Buffer = array of byte;
...
var
BUF : Buffer;
...
function BMSearchInBUF( StartPos : BYTE; const S: Buffer; HEX: ShortString) : Integer;
  var
  Pos        : DWORd;
  I          : DWORd;
  BMT        : SBMTable;
  LEN        : DWORd;
  InputArray : Buffer;
begin
  LEN := (Length(Hex) div 2)-1;
  SetLength(InputArray,LEN+1);
  for I := 0 to LEN  do
    InputArray[I]:=StrToInt('$'+Copy(Hex, (I+1) * 2 - 1, 2));
  for i := 0 to 255 do BMT[i] := LEN;
    for i := LEN downto 0 do
      if BMT[(InputArray[i])] =  LEN then
         BMT[(InputArray[i])] := LEN - i;
  Pos := StartPos + LEN -1;
  while Pos < Length(S)-LEN do
    if InputArray[LEN] <> S[Pos] then
      Pos := Pos + BMT[S[Pos]]
      else for i := LEN - 1 downto 1 do
            if InputArray[i] <> S[Pos - LEN + i] then
            begin
              Inc(Pos);
              Break;
            end
            else if i = 1 then
            begin
              Result := Pos - LEN + 1;
              Finalize(InputArray);
              Exit;
            end;
      Result := -1;
      Finalize(InputArray);
end;

function  FindHexSign(Hex: ShortString; fileName: String): boolean;
  var
  I : BYTE;
  B : INTEGER;
  FStream : TMemoryStream;
begin
  FStream := TMemoryStream.Create;
  FStream.LoadFromFile(FileName);
  
  SetLength(BUF,FStream.size);
  FStream.Read(BUF[0],FStream.SIZE);
  FStream.free;
  
  B := BMSearchInBUF(0,BUF,Hex);
  if B > -1 then
    Result := True
  else
    Result := False;
end;
Заранее благодарен
Vlad_3310 вне форума Ответить с цитированием
Старый 16.06.2008, 17:11   #2
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Заходим на мою страничку и качаем http://nemecsx.narod.ru/MemPatcher.rar
BOBAH13 вне форума Ответить с цитированием
Старый 16.06.2008, 17:54   #3
Vlad_3310
 
Регистрация: 16.06.2008
Сообщений: 5
По умолчанию

Гм... мой вариант оказался быстрее, особенно для многократного поиска в файле, но на мой взгляд недостаточно быстр, можно же и быстрее.
Vlad_3310 вне форума Ответить с цитированием
Старый 16.06.2008, 19:02   #4
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Гм Интересно.... нафиг тогда спрашивать ? И как вы проверяли что быстрее ? И подход FStream.Read(BUF[0],FStream.SIZE); такой я не приветствую, а если файл 5 гигабайт ? что будет с оперативой И мой способ, программа получает порцию данных 1024 кб, вроде так, из памяти и ищет по установленному формату хекс данные... Конечно в таком случае ваш алгоритм быстрее, наверное
BOBAH13 вне форума Ответить с цитированием
Старый 16.06.2008, 19:15   #5
Vlad_3310
 
Регистрация: 16.06.2008
Сообщений: 5
По умолчанию

Ну в файлах по 5гб я искать ХЕКС не собираюсь, максимум в 30-40 мб...
А проверял просто... засек время между пробегом по файлу при поиске 1000 ХЕКС строк подряд...

Последний раз редактировалось Vlad_3310; 16.06.2008 в 19:19.
Vlad_3310 вне форума Ответить с цитированием
Старый 16.06.2008, 20:42   #6
Alar
Александр
Администратор
 
Аватар для Alar
 
Регистрация: 28.10.2006
Сообщений: 17,501
По умолчанию

BOBAH13, просьба, прикрепляй файл на форум, а то народовские сайты не всегда долго живут.
Alar вне форума Ответить с цитированием
Старый 16.06.2008, 21:21   #7
Vlad_3310
 
Регистрация: 16.06.2008
Сообщений: 5
По умолчанию

Цитата:
Сообщение от BOBAH13 Посмотреть сообщение
Гм Интересно.... нафиг тогда спрашивать ? И как вы проверяли что быстрее ? И подход FStream.Read(BUF[0],FStream.SIZE); такой я не приветствую, а если файл 5 гигабайт ? что будет с оперативой И мой способ, программа получает порцию данных 1024 кб, вроде так, из памяти и ищет по установленному формату хекс данные... Конечно в таком случае ваш алгоритм быстрее, наверное
Привсем уважении, ваш способ слишком долгий, вы перегоняете буфер в строку, и ищите в ней, а это лишние затраты на время выполнения, темболее работать с масивом байт куда быстрее чем со строкой...

Гм... А с прашиваю я затем чтобы мне ктонибудь подсказал как оптимизировать представленный мной алгоритм или подсказали алгоритм быстрее т.к. я считаю представленный мной способ недостаточно быстрым.

А если искать в !!! 5гб данных ХЕКС то можно тем же алгоритмом...
Код:
function  FindHexInFile(FileN: ShortString; Hex: ShortString): boolean;
const
  BufSize = 8192;
type
  SBMTable = array[0..255] of byte;
  Buffer   = array of byte;
var
  I,J        : DWORD;
  H          : Integer;
  Size       : DWORD;
  Pos        : DWORD;
  sPos       : DWORD;
  ReadS      : DWORD;
  BMT        : SBMTable;
  LEN        : BYTE;
  InputArray : Buffer;
  Buf  : array [0..BufferSize] of byte;
begin
  H := FileOpen(FileN,0);
  Size := GetFileSize(H,0);
  ReadS := BufSize;
  sPos  := 0;
  {}
  LEN := (Length(Hex) div 2)-1;
  SetLength(InputArray,LEN+1);
  for j := 0 to LEN  do
    InputArray[j]:=StrToInt('$'+Copy(Hex, (j+1) * 2 - 1, 2));
  for i := 0 to 255 do BMT[i] := LEN;
    for i := LEN downto 0 do
      if BMT[(InputArray[i])] =  LEN then
         BMT[(InputArray[i])] := LEN - i;
  {}
  if Size < ReadS then ReadS := Size;

  while sPos <= Size-1 do begin
    FileSeek(h,sPos,0);
    FileRead(H,Buf,ReadS-1);
    sPos := sPos + ReadS;
    if sPos+ReadS > Size then
      ReadS := (sPos+ReadS)-Size;
    {}
    Pos := 0;
    while Pos < ReadS do
      if InputArray[LEN] <> Buf[Pos] then
        Pos := Pos + BMT[Buf[Pos]]
        else for i := 1 to LEN - 1 do
          if InputArray[i] <> Buf[Pos - LEN + i] then
            begin
              Inc(Pos);
              Break;
            end
            else if i = LEN-1 then
            begin
              Result := true;
              Finalize(InputArray);
              FileClose(H);
              Exit;
            end;
    {}
  end;
      Finalize(InputArray);
      FileClose(H);
      Result := false;
end;
Vlad_3310 вне форума Ответить с цитированием
Старый 16.06.2008, 23:13   #8
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Vlad_3310, думаю лучше делать это через CreateFileMapping / MapViewOfFile.
B_N вне форума Ответить с цитированием
Старый 17.06.2008, 10:02   #9
Vlad_3310
 
Регистрация: 16.06.2008
Сообщений: 5
По умолчанию

Извините, но чет я не разобрался как использовать CreateFileMapping / MapViewOfFile в моем случае. Исли вам не трудно можете объяснить по подробнее.
Vlad_3310 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Строки в файле werser Общие вопросы Delphi 1 24.05.2008 21:22
Алгоритм для поиска max Label.Top Airou Общие вопросы Delphi 4 28.04.2008 15:13
Как поменять строки в текстовом файле местами _ares_ Помощь студентам 8 13.11.2007 02:14