Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Синхронизатор: проблема быстрой проверки большого кол-ва файлов [D7, WinXP]


kukuikar ©   (2007-05-16 07:51:00) 

На данном этапе программа работает. Но выплыла проблема проверки идентичности файлов.

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

Все нормально работает при объеме до 6 Гб, файлы весят от 20Кб до 200 Мб.

Мастера, как посоветуете быстро проверять 2 файла на одинаковость?

Заранее спасибо.


clickmaker   (2007-05-17 09:29:00) [1]


> [11] kukuikar ©   (16.05.07 21:09)

CompareMem()

и рекомендую memory mapped files

hFile := CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
                   nil, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
dwSize1 := GetFileSize(hFile1, NULL);
dwSize2 := GetFileSize(hFile2, NULL);
if (dwSize1 = dwSize2) then begin
 hMapping1 := CreateFileMapping(hFile1, nil, PAGE_READONLY, 0, 0, nil);
 ну и т.д.


kukuikar   (2007-05-16 21:09:00) [2]

Побайтово так:?


var
 F1, F2: file;
 B1, B2: array[0..1023] of Char;
 i1, i2: Integer;

repeat
   BlockRead(F1, B1, SizeOf(B1), i1);
   BlockRead(F2, B2, SizeOf(B2), i2);
   if B1 <> B2 then
   begin
     CloseFile(F1);
     CloseFile(F2);
     Exit;
   end;
 until EoF(F2);


kukuikar   (2007-05-16 17:07:00) [3]


> Anatoly Podgoretsky ©   (16.05.07 16:46) [9]

Спасибо. Буду оптимизироваться дальше :)


Anatoly Podgoretsky   (2007-05-16 16:46:00) [4]

> kukuikar  (16.05.2007 15:34:08)  [8]

Вроде все нормально.
А по поводу более подробно, нет нужды считать CRC достаточно считать только контрольную СУММУ, но это тоже не оптимально, более оптимально просто сравнивать по 4 байта (с учетом конца) и прекращать при первом несравнении, может быть гигантский выигрыш по скорости, например при несравнение первых 4 байт, нет нужды читать остальные 200 мегабайт. Тоже тебе советовал Леонид Трояновский и при этом никаких коллизий.


kukuikar   (2007-05-16 15:34:00) [5]

Кстати я не сказал. Все это дело сбрасывается на сервер в локалке. Скорости хватает,гигабитная сеть.
С оптимизацией проверки разобрались. Буду сравнивать так:


function TfrmMain.CompareFileDates(const FirstFile, SecondFile: string): Boolean;
begin
Result := GetFileDate(FirstFile) = GetFileDate(SecondFile);
end;

function TfrmMain.GetFileDate(FileName: string): Integer;
var
 FHandle: Integer;
begin
 FHandle := FileOpen(FileName, fmShareDenyNone);
 try
   Result := FileGetDate(FHandle);
 finally
   FileClose(FHandle);
 end;
end;


А как насчет копирования, я копирую так:


function CallBackfnsForCopyFileEx(TotalFileSize, TotalBytesTransferred, StreamSize, StreamBytesTransferred: large_integer; DWStreamNumber, DWCallbackReason: Dword; HSourceFile, HDestinationFile: THandle; LpData: Pointer): Dword; stdcall;
begin
if DWCallbackReason = Callback_Stream_Switch then
 TGauge(LpData).MaxValue := TotalFileSize.QuadPart;
TGauge(LpData).Progress := TotalBytesTransferred.QuadPart;
Application.ProcessMessages;
Result := Progress_Continue;
end;

function TfrmMain.CopyWithProgress(SSource, SDest: String): Boolean;
begin
Result := CopyFileEx(PChar(SSource), PChar(SDest), @CallBackfnsForCopyFileEx, frmProgress.pf, nil, 0);
end;


Что скажете?


> Anatoly Podgoretsky ©   (16.05.07 11:53) [6]

Непонял, а поподробнее немного можно?


Leonid Troyanovsky   (2007-05-16 15:09:00) [6]


> clickmaker ©   (16.05.07 09:40) [3]

> > как посоветуете быстро проверять 2 файла на одинаковость?

> чтоб уж наверняка - считай контрольную сумму. CRC32

Чтобы наверняка, то нужно сравнивать сами файлы.
Т.е., читаем в буферы, сравниваем два буфера и т.д.
Любые хеш-функции здесь только лишние.

--
Regards, LVT.


Anatoly Podgoretsky   (2007-05-16 11:53:00) [7]


> Для файлов больших размеров долго очень считается CRC32

А ты оптимально читаешь файлы? Может ты по байтам работаешь?
Сделай более простой подсчет, например N := N + F(I) и тип Integer


clickmaker   (2007-05-16 10:08:00) [8]


> долго очень считается CRC32

ну там тоже есть простор для оптимизации
memory mapped files, к примеру


kukuikar   (2007-05-16 10:02:00) [9]


> чтоб уж наверняка - считай контрольную сумму. CRC32

Пробовал.
Для файлов больших размеров долго очень считается CRC32


clickmaker   (2007-05-16 09:40:00) [10]


> как посоветуете быстро проверять 2 файла на одинаковость?

чтоб уж наверняка - считай контрольную сумму. CRC32


Loginov Dmitry   (2007-05-16 09:04:00) [11]

> Мастера, как посоветуете быстро проверять 2 файла на одинаковость?


Так и проверяй - по дате и размеру файла. А чтобы быстро проверка работала - оптимизируй алгоритм. Вообще подобным образом сравнение 500 файлов должно занимать не более 0.5 сек.


Elen   (2007-05-16 08:13:00) [12]


>  Я проверяю дату последнего изменения файла и если дата
> изменена то копирую его.

Я делаю так : Организовываю две базы, одна предидущая другая новая (сегодняшняя). Далее простым запросом получаю список измененных файлов и уже их обрабатываю.


Наверх

Титульная страница Поиск, карта сайта Написать письмо