![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ошибка при сравнении 2 файлов [D7, XP]
kukuikar © (2006-12-20 18:43:00)Имею такую функцию для сравнения 2-х файлов:
function TfrmMain.CompareFiles(const FirstFile, SecondFile: string): Boolean;
var
f1, f2: TMemoryStream;
begin
Result := false;
f1 := TMemoryStream.Create;
f2 := TMemoryStream.Create;
try
f1.LoadFromFile(FirstFile);
f2.LoadFromFile(SecondFile);
if IOResult <> 0 then
Result := false;
if f1.Size = f2.Size then //n?aaieaaai ii ?acia?o...
Result := CompareMem(f1.Memory, f2.memory, f1.Size);
end;
finally
f2.Free;
f1.Free;
end
end;
Так вот. Ошибка вываливается при проверке 2 файлов, один из которых открыт другой программой. Немогу понять как это обойти.
umbra (2006-12-21 14:56:00) [1]ошибка была из-за того, что метод
TMemoryStream.LoadFromFileпытается открыть файл в режимеfmShareDenyWrite(т.е. пытается запретить другим приложениям писать в него). Соответственно, если другая программа уже открыла файл для записи (например, в режимеfmOpenWrite), то при выполнении этого метода случится исключение.
kukuikar (2006-12-21 14:50:00) [2]Черт...!
> fs1 := TFileStream.Create(FirstFile, fmOpenRead);
> fs2 := TFileStream.Create(SecondFile, fmOpenRead);
Здесь конечно же
fs1 := TFileStream.Create(FirstFile, fmDenyShareNone);
fs2 := TFileStream.Create(SecondFile, fmDenyShareNone);
kukuikar (2006-12-21 14:42:00) [3]После некоторых манипуляций получилось вот что.
Функция сравнения двух файлов:
function TfrmMain.CompareFiles(const FirstFile, SecondFile: string): Boolean;
var
f1, f2: TMemoryStream;
fs1, fs2: TFileStream;
begin
fs1 := TFileStream.Create(FirstFile, fmOpenRead);
fs2 := TFileStream.Create(SecondFile, fmOpenRead);
Result := false;
f1 := TMemoryStream.Create;
f2 := TMemoryStream.Create;
try
//f1.LoadFromFile(FirstFile);
f1.LoadFromStream(fs1);
//f2.LoadFromFile(SecondFile);
f2.LoadFromStream(fs2);
if f1.Size = f2.Size then
Result := CompareMem(f1.Memory, f2.memory, f1.Size);
finally
f2.Free;
f1.Free;
end
end;
А вот цикл где эта функция используется:
for i := 0 to FileList.Count - 1 do
begin
frmProgress.pa.Progress := i;
frmProgress.lbFname.Caption := FileList.Strings[i];
ToFile := ToList.Strings[i];
FromFile := FileList.Strings[i];
if not DirectoryExists(ExtractFilePath(ToFile)) then
ForceDirectories(ExtractFilePath(ToFile));//Если конечная папка несуществует, то создаем путь до нее
if (not FileExists(ToFile)) or (not CompareFiles(ToFile,FromFile)) then
begin
if CopyWithProgress(FromFile,ToFile) then
Inc(k)//счетчик скопированных фалов
else
WriteLog('Ошибка копирования файла: ' + FromFile);
end
else
Inc(j);//счетчик пропущенных файлов
Application.ProcessMessages;
if ab then
Break;//если наэата кнопка прервать, то выход из цикла
end;
Ошибка происходила когда цикл сравнивал 2 файла и исходный (оригинал) был открыт (в режиме fmOpenRead или вообще через TMemoryStream). Так вот, после того как я через TFileStream открыл в режиме fmShareDenyNone, ошибка перестала вываливаться (при окрытом исходном файле).
Anatoly Podgoretsky (2006-12-21 11:48:00) [4]> kukuikar (21.12.2006 10:46:06) [6]
> Знать бы еще что это за режим... :)
Описано в справке, да и из названия понятно - если другая программа попробует открыть файл, то она ошибки не получит.
> fmShareDenyNone Allows full access for others.
К твоей проблеме отношения не имеет, ты наверно кроме этого еще и открыл файл в режиме только чтения, может даже не подозревая об этом. Код то ты не приводишь.
kukuikar (2006-12-21 10:48:00) [5]
> а если они размером по гигабайту каждый?
Таких у нас точно не будет. :)
> но вообще-то довольно странный способ сравнивать файлы.
А как еще сравнить? CRC или MD5? Посоветуйте, мастера...
umbra (2006-12-21 10:46:00) [6]но вообще-то довольно странный способ сравнивать файлы. а если они размером по гигабайту каждый?
kukuikar (2006-12-21 10:46:00) [7]Сработало с TFileStream в режиме fmShareDenyNone.
Знать бы еще что это за режим... :)
kukuikar (2006-12-21 09:49:00) [8]
> Какая ошибка?
Говорит что немогу получить доступ к файлу, т.к. он открыт другой программой.
> П.С. IOResult ни причем вообще.
Да. Я знаю. Забыл вытереть просто. IOResult понятно непричем.
> umbra © (20.12.06 19:02) [2]
Спасибо, попробую.
Джо (2006-12-20 19:03:00) [9]> Так вот. Ошибка вываливается при проверке 2 файлов
Какая ошибка?
П.С. IOResult ни причем вообще.
umbra (2006-12-20 19:02:00) [10]Ошибка будет случаться каждый раз, если файл открыт другой программой на запись. Можно попробовать открыть файл с помощью
TFileStreamв режимеfmOpenRead, а затем скопировать его содержимое вMemoryStream. Но и при этом ошибка будет случаться, если другая программа открыла файл эксклюзивно.
kukuikar (2006-12-20 18:44:00) [11]А скопировать могу открытый файл без проблем...