Kako provjeriti da li je datoteka mjenjana ali bez pregledavanja sadržaja i upoređivanja. Probao sam sa vremenom zadnje promjene datoteke ali nije upotrebljivo jer su promjene unutar jedne sekunde. Znači procedura kreira datoteku i upisuje podatke u nju, drugi program vrši obradu i ako treba ostavlja "trag". Onda ispočetka, prva procedura treba samo podatak da li je nešto mjenjano, nebitno šta.
Provjera, da li je datotaka mjenjana?
Zaključano
Zakačeno
FAT sistemi imaju rezoluciju od 10ms za create, 2sec za write i 1day (nije greška, preuzeto iz MSDNa) za access time. Kod NTFSa je bolja situacija ali samo piše da je za last access time 1 sat, verovatno je za write unutar sekunde.
Osim provere sadržaja (to se efikasno radi prostim računanjem CRCa) možeš koristiti ReadDirectoryChangesW, ali ni tu nisam siguran kako će se ponašati kod čestih izmena. Inače, ako imaš kontrolu nad oba programa, onda jednostavno pošalji obaveštenje prvom da je došlo do promene.
Osim provere sadržaja (to se efikasno radi prostim računanjem CRCa) možeš koristiti ReadDirectoryChangesW, ali ni tu nisam siguran kako će se ponašati kod čestih izmena. Inače, ako imaš kontrolu nad oba programa, onda jednostavno pošalji obaveštenje prvom da je došlo do promene.
Potpis
Do not be a help vampire (http://slash7.com/pages/vampires), use the google.
How to ask questions the smart way:
http://www.catb.org/~esr/faqs/smart-questions.html
http://solair.eunet.rs/~fangor...stions/smart-questions.sr.html
How to ask questions the smart way:
http://www.catb.org/~esr/faqs/smart-questions.html
http://solair.eunet.rs/~fangor...stions/smart-questions.sr.html
Sve bi bilo prosto da imam kontrolu...
Mozes da koristis tzv. change notifikacije koristeci windows API. Preko Find(First/Next)ChangeNotification dobijes win handle od waitobj-a koji prati promene datoteke i onda cekas na promene sa WaitForSingleObject. Jedini problem je to sto je WaitForSingleObject tzv. blocking poziv, sto znaci da ce ti blokirati glavni thread ako ga pozoves iz njega (sto i nije neki problem ako program samo to radi, npr. servisna aplikacija koja ceka na promenu, onda nesto cacka pa onda ceka ne sledecu promenu...). Logicno resenje ja da cekas iz worker thread-a koji nece blokirati glavni thread. Evo ti kompletna klasa koja to radi:
Klasu koristis sa
Klasa je fire-and-forget jer koristi FreeOnTerminate.
Medjutim izgleda mi da tebi ovo treba da bi ostvario komunikaciju izmedju dva programa. Ako si ti autor oba programa onda je mozda bolje da potrazis nesto na temu memory mapped files ili shared memory, daleko bolji nacin za interprocesnu komunikaciju na istoj masini.
Code:
unit FileMonitor;
interface
uses
Classes, Windows, SysUtils;
type
TFileMonitor = class(TThread)
private
FFileName: String;
{ Private declarations }
protected
procedure Execute; override;
procedure DoSomething;
public
destructor Destroy; override;
procedure StartMonitoring(Filename: String);
end;
implementation
{ TFileMonitor }
destructor TFileMonitor.Destroy;
begin
inherited;
end;
procedure TFileMonitor.DoSomething;
begin
//tvoj kod za obradu promene
end;
procedure TFileMonitor.Execute;
var
H: Cardinal;
begin
H := FindFirstChangeNotification(PChar(FFileName), False, FILE_NOTIFY_CHANGE_LAST_WRITE or FILE_NOTIFY_CHANGE_FILE_NAME);
if H = INVALID_HANDLE_VALUE then
Terminate
else
try
while not Terminated do
begin
WaitForSingleObject(H, INFINITE);
if not FileExists(FFileName) then
begin
Terminate;
break;
end;
Synchronize(DoSomething);
if not FindNextChangeNotification(H) then
begin
Terminate;
break;
end;
end;
finally
FindCloseChangeNotification(H);
end;
end;
procedure TFileMonitor.StartMonitoring(FileName: String);
begin
FFileName := FileName;
Self.FreeOnTerminate := True;
Resume;
end;
end.
unit FileMonitor;
interface
uses
Classes, Windows, SysUtils;
type
TFileMonitor = class(TThread)
private
FFileName: String;
{ Private declarations }
protected
procedure Execute; override;
procedure DoSomething;
public
destructor Destroy; override;
procedure StartMonitoring(Filename: String);
end;
implementation
{ TFileMonitor }
destructor TFileMonitor.Destroy;
begin
inherited;
end;
procedure TFileMonitor.DoSomething;
begin
//tvoj kod za obradu promene
end;
procedure TFileMonitor.Execute;
var
H: Cardinal;
begin
H := FindFirstChangeNotification(PChar(FFileName), False, FILE_NOTIFY_CHANGE_LAST_WRITE or FILE_NOTIFY_CHANGE_FILE_NAME);
if H = INVALID_HANDLE_VALUE then
Terminate
else
try
while not Terminated do
begin
WaitForSingleObject(H, INFINITE);
if not FileExists(FFileName) then
begin
Terminate;
break;
end;
Synchronize(DoSomething);
if not FindNextChangeNotification(H) then
begin
Terminate;
break;
end;
end;
finally
FindCloseChangeNotification(H);
end;
end;
procedure TFileMonitor.StartMonitoring(FileName: String);
begin
FFileName := FileName;
Self.FreeOnTerminate := True;
Resume;
end;
end.
Klasu koristis sa
Code:
TFileMonitor.Create.StartMonitoring('C:\Path\File.ext');
TFileMonitor.Create.StartMonitoring('C:\Path\File.ext');
Klasa je fire-and-forget jer koristi FreeOnTerminate.
Medjutim izgleda mi da tebi ovo treba da bi ostvario komunikaciju izmedju dva programa. Ako si ti autor oba programa onda je mozda bolje da potrazis nesto na temu memory mapped files ili shared memory, daleko bolji nacin za interprocesnu komunikaciju na istoj masini.
Potpis
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
impersonation.
Možeš koristiti i HASH provjeru.
OP je lepo napisao "Kako provjeriti da li je datoteka mjenjana ali bez pregledavanja sadržaja i upoređivanja". Ja ne znam ni za kakav hash algoritam koji bi to izveo uz postovanje uslova pod navodnicima.
Potpis
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
impersonation.