Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.01.14;
Скачать: CL | DM;

Вниз

Ошибка при сравнении 2 файлов   Найти похожие ветки 

 
kukuikar ©   (2006-12-20 18:43) [0]

Имею такую функцию для сравнения 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 файлов, один из которых открыт другой программой. Немогу понять как это обойти.


 
kukuikar ©   (2006-12-20 18:44) [1]

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


 
umbra ©   (2006-12-20 19:02) [2]

Ошибка будет случаться каждый раз, если файл открыт другой программой на запись. Можно попробовать открыть файл с помощью TFileStream в режиме fmOpenRead, а затем скопировать его содержимое в MemoryStream. Но и при этом ошибка будет случаться, если другая программа открыла файл эксклюзивно.


 
Джо ©   (2006-12-20 19:03) [3]

> Так вот. Ошибка вываливается при проверке 2 файлов

Какая ошибка?

П.С. IOResult ни причем вообще.


 
kukuikar ©   (2006-12-21 09:49) [4]


> Какая ошибка?

Говорит что немогу получить доступ к файлу, т.к. он открыт другой программой.


> П.С. IOResult ни причем вообще.

Да. Я знаю. Забыл вытереть просто. IOResult понятно непричем.


> umbra ©   (20.12.06 19:02) [2]

Спасибо, попробую.


 
umbra ©   (2006-12-21 10:46) [5]

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


 
kukuikar ©   (2006-12-21 10:46) [6]

Сработало с TFileStream в режиме fmShareDenyNone.
Знать бы еще что это за режим... :)


 
kukuikar ©   (2006-12-21 10:48) [7]


> а если они размером по гигабайту каждый?

Таких у нас точно не будет. :)


> но вообще-то довольно странный способ сравнивать файлы.

А как еще сравнить? CRC или MD5? Посоветуйте, мастера...


 
Anatoly Podgoretsky ©   (2006-12-21 11:48) [8]

> kukuikar  (21.12.2006 10:46:06)  [6]

> Знать бы еще что это за режим... :)

Описано в справке, да и из названия понятно - если другая программа попробует открыть файл, то она ошибки не получит.

> fmShareDenyNone   Allows full access for others.

К твоей проблеме отношения не имеет, ты наверно кроме этого еще и открыл файл в режиме только чтения, может даже не подозревая об этом. Код то ты не приводишь.


 
kukuikar ©   (2006-12-21 14:42) [9]

После некоторых манипуляций получилось вот что.

Функция сравнения двух файлов:
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, ошибка перестала вываливаться (при окрытом исходном файле).


 
kukuikar ©   (2006-12-21 14:50) [10]

Черт...!

> fs1 := TFileStream.Create(FirstFile, fmOpenRead);
> fs2 := TFileStream.Create(SecondFile, fmOpenRead);


Здесь конечно же
fs1 := TFileStream.Create(FirstFile, fmDenyShareNone);
fs2 := TFileStream.Create(SecondFile, fmDenyShareNone);


 
umbra ©   (2006-12-21 14:56) [11]

ошибка была из-за того, что метод TMemoryStream.LoadFromFile пытается открыть файл в режиме fmShareDenyWrite (т.е. пытается запретить другим приложениям писать в него). Соответственно, если другая программа уже открыла файл для записи (например, в режиме fmOpenWrite), то при выполнении этого метода случится исключение.



Страницы: 1 вся ветка

Текущий архив: 2007.01.14;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.208 c
1-1164296458
DelphiLexx
2006-11-23 18:40
2007.01.14
Delphi 2006 и TFlowPanel, TGridPanel


15-1166645169
IMHO
2006-12-20 23:06
2007.01.14
Покачать фильмы и сериалы


15-1166725442
Tirael
2006-12-21 21:24
2007.01.14
срочно нудно достать пароль из бата


8-1148270922
igorek_2005
2006-05-22 08:08
2007.01.14
Как проиграть Flash-exe


2-1166618448
регинка
2006-12-20 15:40
2007.01.14
как нам тяжело новичкам