Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как сравнить содержимое двух файлов? (нужен самый быстрый способ) 
V
    Опции темы
Тутанхамец
Дата 29.3.2006, 08:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 10.10.2005
Где: в пирамидЕ!

Репутация: 1
Всего: 6



Здравствуйте, уважаемые! Нужен совет.
Моей проге надо проверять файлы на "одинаковость". В том числе и по содержимому. Файлы могут быть любого размера, и их может быть большое количество. Я думаю использовать такую незамысловатую функцию:

Код

function TAC.CompareFiles(sFile1 :string; sFile2:string):boolean;
var
  f1,f2:TFileStream;
  m1,m2:array of bytes;
  n1,n2:int64;
  i:cardinal;
begin
  result:=false;
  f1:=TFileStream.create(sfile1,fmOpenRead+fmShareDenyNone);
  f2:=TFileStream.create(sfile2,fmOpenRead+fmShareDenyNone);
  n1:=f1.size;
  n2:=f2.size;
  if (n1<>n2) or (n1>high(cardinal)) or (n2>high(cardinal)) then exit;  //пусть пока ТАКИЕ большие файлы не проверяются.
  setlength(m1,n1);
  setlength(m2,n2);
  f1.readbuffer(m1,n1);
  f2.readbuffer(m2,n2);
  for i:=0 to n1 do
    if m1[i]<>m2[i] then exit;
  result:=true;
  setlength(m1,0);
  setlength(m2,0);
  freeandnil(f1);
  freeandnil(f2);
end;


Кто-нибудь может подсказать более быстрый вариант?

Это сообщение отредактировал(а) Тутанхамец - 29.3.2006, 09:18
PM MAIL   Вверх
Matematik
Дата 29.3.2006, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1027
Регистрация: 11.3.2006

Репутация: 17
Всего: 50



Эта тема уже обсуждалась. Воспользуйся поиском.
А вообще один из самых быстрых способов это MMF (File Mapping)
PM MAIL WWW ICQ   Вверх
Тутанхамец
Дата 29.3.2006, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 10.10.2005
Где: в пирамидЕ!

Репутация: 1
Всего: 6



В поиске искал минут сорок, ничего не нарыл. Прошу прощения. smile Спасибо насчет MMF. Мысль была, но я не думал, что это будет быстрее. А как, по твоему, быстрее с MMF - сравнивать побайтно или (тут еще подсказали) загонять восемь байт в число int64 и сравнивать эти числа?
PM MAIL   Вверх
Matematik
Дата 29.3.2006, 09:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1027
Регистрация: 11.3.2006

Репутация: 17
Всего: 50



Например CompareMem
PM MAIL WWW ICQ   Вверх
Тутанхамец
Дата 29.3.2006, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 10.10.2005
Где: в пирамидЕ!

Репутация: 1
Всего: 6



Понял. Ступил я. Написал неправльное слово для поиска, потому ничего не нашел в тот раз. Сейчас написал правильно и нашел ту тему. Спасибо еще раз. smile Вопрос закрыт.
PM MAIL   Вверх
Guedda
Дата 29.3.2006, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


Профиль
Группа: Завсегдатай
Сообщений: 3137
Регистрация: 27.12.2005
Где: Ростов-на-Дону

Репутация: 14
Всего: 78



Вот моя функция. Считаю ее быстрой:
Код

const {Result in CompareFiles}
  CF_REPLACE_PATH        = $00A; // Имя и путь 1 и 2 файлов идентичны
  CF_NOT_ASSIGNED_FIRST  = $00B; // Ошибка связи с первым файлом
  CF_NOT_ASSIGNED_SECOND = $00C; // Ошибка связи со вторым файлом
  CF_FILES_NAME_IDENT    = $00D; // Файлы идентичны по именам
  CF_FILES_IDENTIFIED    = $00E; // Файлы идентичны
  CF_ERROR_FILE_SIZE     = $00F; // Размеры файлов не равны
  CF_BYTES_NOT_COMP      = $010; // Размеры считываемых байтов не идентичны
  CF_BYTE_NOT_COMP       = $011; // Считываемые байты не идентичны
  CF_OTHER_ERROR         = $012; // Найдены другие ошибки


function CompareFiles(FileName1, FileName2 : PChar; Buf_Size : LongInt) : byte; stdcall;
var
  File1, File2 : string;
  FS1, FS2 : TFileStream;
  Buff1, Buff2 : PByteArray;
  BytesRead1, BytesRead2 : Integer;
  FileNotPath1, FileNotPath2 : string;
  DJ : LongInt;
  
  function CompareStr(const S1, S2: string): Integer; assembler;
  asm
          PUSH    ESI
          PUSH    EDI
          MOV     ESI,EAX
          MOV     EDI,EDX
          OR      EAX,EAX
          JE      @@1
          MOV     EAX,[EAX-4]
  @@1:    OR      EDX,EDX
          JE      @@2
          MOV     EDX,[EDX-4]
  @@2:    MOV     ECX,EAX
          CMP     ECX,EDX
          JBE     @@3
          MOV     ECX,EDX
  @@3:    CMP     ECX,ECX
          REPE    CMPSB
          JE      @@4
          MOVZX   EAX,BYTE PTR [ESI-1]
          MOVZX   EDX,BYTE PTR [EDI-1]
  @@4:    SUB     EAX,EDX
          POP     EDI
          POP     ESI
  end;

begin
  File1 := FileName1;
  File2 := FileName2;
  Result := CF_FILES_IDENTIFIED;
  if File1 = File2 then begin
    Result := CF_REPLACE_PATH;
    Exit;
  end;
  FileNotPath1 := ChopPath(File1);
  FileNotPath2 := ChopPath(File2);
  if CompareStr(FileNotPath1, FileNotPath2) = 0 then begin
    Result := CF_FILES_NAME_IDENT;
    Exit;
  end;
  try
    FS1 := TFileStream.Create(File1, fmShareDenyNone);
  except
    Result := CF_NOT_ASSIGNED_FIRST;
    Exit;
  end;
  try
    FS2 := TFileStream.Create(File2, fmShareDenyNone);
  except
    Result := CF_NOT_ASSIGNED_SECOND;
    FS1.Free;
    Exit;
  end;
  GetMem(Buff1, Buf_Size);
  GetMem(Buff2, Buf_Size);
  try
    if FS1.Size <> FS2.Size then Result := CF_ERROR_FILE_SIZE
    else
    while (FS1.Size <> FS1.Position) and (Result = CF_FILES_IDENTIFIED) do begin
      BytesRead1 := FS1.Read(Buff1^, Buf_Size);
      BytesRead2 := FS2.Read(Buff2^, Buf_Size);
      if (BytesRead1 = BytesRead2) then begin
        for DJ := 0 to BytesRead1 - 2 do begin
          if Buff1^[DJ] <> Buff2^[DJ] then begin
            Result := CF_BYTE_NOT_COMP;
            Break;
          end;
        end;
      end else begin
        Result := CF_BYTES_NOT_COMP;
        Break;
      end;
    end;
  except
    Result := CF_OTHER_ERROR;
  end;
  FreeMem(Buff1);
  FreeMem(Buff2);
  FS1.Free;
  FS2.Free;
end;

Взято из моей программы поэтому работает 100%


--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
Alexeis
Дата 29.3.2006, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Guedda, функция очень быстрая - ускорить можно еще на пол процента если файлы целиком читать в память за один проход (да и то если он на диске не фрагментированsmile )


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Тутанхамец
Дата 30.3.2006, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 10.10.2005
Где: в пирамидЕ!

Репутация: 1
Всего: 6



Монструозо... smile Это комплимент. smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0572 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.