![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Идентично, сэр? [D7, WinXP]
WhiteGuy © (2005-01-05 18:21:00)Здорово, мужики! Уже третий раз за сегодня здороваюсь! 8-)
Как проверить два файла на идентичность?
И, если можно, код! :)
GuAV (2005-01-05 19:05:00) [1]IMHO, MMF + Comparemem
begin...end (2005-01-05 18:43:00) [2]> WhiteGuy (05.01.05 18:21)
Ну, во-первых, для проверки на НЕидентичность можно использовать контрольную сумму (поиск в Яндексе по буквосочетанию CRC).
Я бы сделал проверку на идентичность (если имеется в виду именно идентичность содержимого файлов) примерно так. Вначале проверил бы на одинаковость размера - если размеры различаются, то, естественно, файлы неодинаковые. Затем считывал бы из каждого файла куски данных и сравнивал бы их побайтно до обнаружения первого несовпадения или до достижения конца файла.
var
// Имена файлов
FileName1, FileName2: String;
// Потоки, с помощью которых можно читать из файлов
FileStream1, FileStream2: TFileStream;
// Указатели на буферы, в которых будут очередные куски данных из файлов
Buffer1, Buffer2: Pointer;
// Размер каждого буфера
// Над размером нужно хорошо подумать
BufferSize: Integer;
// Количество считанных байт на очередном проходе
// Вообще-то эти переменные должны быть равны, но так... на всякий случай...
BytesCount1, BytesCount2: Integer;
// Переменная, указывающая на идентичность файлов
Ident: Boolean;
begin
FileStream1 := TFileStream.Create(FileName1, fmShareDenyNone);
FileStream2 := TFileStream.Create(FileName2, fmShareDenyNone);
if FileStream1.Size <> FileStream2.Size then
begin
// До свидания, размеры неодинаковые
FileStream1.Free;
FileStream2.Free
end
else
begin
BufferSize := {здесь хорошо думаем};
// Выделяем память для буферов
GetMem(Buffer1, BufferSize);
GetMem(Buffer2, BufferSize);
try
repeat
BytesCount1 := FileStream1.Read(Buffer1^, BufferSize);
BytesCount2 := FileStream2.Read(Buffer2^, BufferSize);
if BytesCount1 = BytesCount2 then
// Непосредственно сравнение кусочков
Ident := CompareMem(Buffer1, Buffer2, BufferSize);
until (not Ident) or (BytesCount1 < BufferSize) or (BytesCount2 < BufferSize);
finally
// Что бы ни случилось, освобождаем драгоценную память
FileStream1.Free;
FileStream2.Free;
FreeMem(Buffer1, BufferSize);
FreeMem(Buffer2, BufferSize)
end
end
end.
В заключение скажу, что если файлы небольшие, то можно обойтись и без цикла, а разом считывать в буфер весь файл (первый и второй), и потом также сравнивать (CompareMem).
Вместо потоков можно также использовать нетипизированные файлы.
Просто Джо (2005-01-05 18:34:00) [3]А может нужно содержимое файлов сравнить? Ты скажи, не стесняйся ;)
Может, тогда и про CompareMem напомнят...
Просто Джо (2005-01-05 18:28:00) [4]Если имя файла, то SysUtils в помощь, функция SameFileName (D6) или AnsiCompareFileName
Просто Джо (2005-01-05 18:28:00) [5]Но что есть идентичность?
Просто Джо (2005-01-05 18:26:00) [6]Что есть идентичность, сэр?