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

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

Ошибка при сравнении 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]

А скопировать могу открытый файл без проблем...


Наверх

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