如何判断某一目录下的文件是否发生了变化?(200分)

  • 主题发起人 主题发起人 tempc
  • 开始时间 开始时间
T

tempc

Unregistered / Unconfirmed
GUEST, unregistred user!
如何判断某一目录下的文件是否发生了变化,如有新文件创建,有文件被删除,修改等?
 
给你一个监视某目录变化的例子:

unit Unit1;

interface

uses
; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
; StdCtrls;

type
; TForm1 = class(TForm)
; ; Button1: TButton;
; ; Edit1: TEdit;
; ; Label1: TLabel;
; ; Button2: TButton;
; ; procedure Button1Click(Sender: TObject);
; ; procedure FormClose(Sender: TObject; var Action: TCloseAction);
; ; procedure Button2Click(Sender: TObject);
; private
; ; { Private declarations }
; public
; ; { Public declarations }
; end;

var
; Form1: TForm1;
; ChangeHandle: THandle;
; CanTerminated: boolean = false;
; Hd: Thandle;

implementation

{$R *.DFM}

function Watch: boolean;
begin
; result := true;
; ChangeHandle := FindFirstChangeNotification(pchar(Form1.edit1.text), false,
; ; ; ; ; ; ; ; ; FILE_NOTIFY_CHANGE_FILE_NAME or
; ; ; ; ; ; ; ; ; FILE_NOTIFY_CHANGE_DIR_NAME or
; ; ; ; ; ; ; ; ; FILE_NOTIFY_CHANGE_ATTRIBUTES or
; ; ; ; ; ; ; ; ; FILE_NOTIFY_CHANGE_SIZE or
; ; ; ; ; ; ; ; ; FILE_NOTIFY_CHANGE_LAST_WRITE);
; if ChangeHandle <> INVALID_HANDLE_VALUE then
; while true do
; begin
; ;if WaitForSingleObject(ChangeHandle, 50) = WAIT_OBJECT_0 then
; ;begin
; ; Form1.label1.caption := 'Changed: True';
; ; application.Restore;
; ; Form1.SetFocus;
; ; exit;
; ;end;
; ;FindNextChangeNotification(ChangeHandle);
; ;if CanTerminated then Break;
; end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
; a: DWord;
begin
; application.Minimize;
; CanTerminated := false;
; HD := CreateThread(nil, 0, @Watch, nil, 0, a);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
; if ChangeHandle <> NULL then FindCloseChangeNotification(ChangeHandle);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
; label1.caption := 'Changed: False';
; TerminateThread(Hd, 0);
end;

end.
 
to beta:
; ;看不太懂,不过感觉要用多线程实现。如果是这样那就太浪费资源了,只是为了判断
文件有没有变化,就用一个循环或者线程整天盯着,好像没必要吧。我只是想在某一特定
的时刻,如用户保存完文件后,判断一下当前目录的文件是否有变化而已。
 
先记下原来文件的修改时间,然后对比现在的,如果不同则被修改
 
好像不用那么麻烦
好像有一个Winaip函数可以监视目录变化
如有变化它就回钓一个你注册的过程

等我给你找找
 
Windows提供了一组API用于检测目录是否变化。
下面是一个检测目录变化的控件。

{$D-}
unit DiskChangeEx;

uses
; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;


type
; TNotifyFilterTypeEx = (FILE_NAME,
; ; ; ; ; ; ; ; ; ; ; ; ;DIR_NAME,
; ; ; ; ; ; ; ; ; ; ; ; ;ATTRIBUTES,
; ; ; ; ; ; ; ; ; ; ; ; ;SIZE,
; ; ; ; ; ; ; ; ; ; ; ; ;LAST_WRITE,
; ; ; ; ; ; ; ; ; ; ; ; ;SECURITY);
; TNotifyFiltersEx = set of TNotifyFilterTypeEx;

; TFileChangeEventEx = procedure (Sender : TObject; NewFiles, DeletedFiles : TStringList) of object;

; TDiskChangeNotifyEx = class;

; TScanThread = class (TThread)
; private
; ; DCN : TDiskChangeNotifyEx;
; ; IsInit : boolean;
; ; EnableNotify : boolean;
; ; procedure NotifyDCN;
; public
; ; constructor Create (DoInit : boolean);
; ; procedure Execute; override;
; end;

; TDiskWatchThreadEx = class (TThread)
; private
; ; DCN : TDiskChangeNotifyEx;
; ; procedure NotifyDCN;
; public
; ; procedure Execute; override;
; end;

; TDiskChangeNotifyEx = class(TComponent)
; private
; ; WatchThread : TDiskWatchThreadEx;
; ; ScanThread : TScanThread;
; ; FWatchSubTree : boolean;
; ; FEnabled : boolean;
; ; FWatchDir : string;
; ; FOnDiskChange : TNotifyEvent;
; ; FNotifyFilter : TNotifyFiltersEx;
; ; NotifyFilterW : word;
; ; FFileChangeEvent : ;TFileChangeEventEx;
; ; FFileExts : string;
; ; FUseTimer : boolean;
; ; FTimerDelay : integer;
; ; FMaintainedDirList : boolean;
; ; FTimer : TTimer;
; ; procedure CreateWatchThread;
; ; procedure DestroyWatchThread;
; protected
; ; procedure SetWatchSubTree (Value : boolean);
; ; procedure SetEnabled (Value : boolean);
; ; procedure SetWatchDir (Value : string);
; ; procedure SetNotifyFilter (Filters : TNotifyFiltersEx);
; ; procedure ScanTerminated (Completed : boolean);
; ; procedure ChangeNotification;
; ; procedure DoNotification (Sender : TObject);
; public
; ; Busy : boolean;
; ; CurrentDirList : TStringList;
; ; NewFilesList : TStringList;
; ; DeletedFilesList : TStringList;
; ; constructor Create (AOwner : TComponent); override;
; ; destructor Destroy; override;
; published
; ; property WatchDir : string read FWatchDir write SetWatchDir;
; ; property WatchSubTree : boolean read FWatchSubTree write SetWatchSubTree default true;
; ; property Enabled : boolean read FEnabled write SetEnabled default false;
; ; property NotifyFilter : TNotifyFiltersEx read FNotifyFilter write SetNotifyFilter;
; ; property FileExtensions : string read FFileExts write FFileExts;
; ; property UseTimer : boolean read FUseTimer write FUseTimer;
; ; property TimerDelay : integer read FTimerDelay write FTimerDelay;
; ; property MaintainedDirList : boolean read FMaintainedDirList write FMaintainedDirList;

; ; property OnDiskChange : TNotifyEvent read FOnDiskChange write FOnDiskChange;
; ; property OnFilesChanged : TFileChangeEventEx read FFileChangeEvent write FFileChangeEvent;
; end;

procedure Register;

// ------------------------------------------------------------------------------ //
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; implementation
// ------------------------------------------------------------------------------ //

procedure Register;
begin
; RegisterComponents('Gamit', [TDiskChangeNotifyEx]);
end;

// ------------------------------------------------------------------------------ //
constructor TScanThread.Create (DoInit : boolean);
begin
; inherited Create (true); // Create suspended
; IsInit := DoInit;
; EnableNotify := true;
end;

procedure TScanThread.NotifyDCN;
begin
; DCN.ScanTerminated (not Terminated);
end;

procedure TScanThread.Execute;
var
; SRes : integer;
; SRec : TSearchRec;
; NewDList, NewFiles, DeletedFiles : TStringList;
; i : integer;
begin
; DCN.Busy := true;
; NewDList := TStringList.Create;
; NewFiles := TStringList.Create;
; DeletedFiles := TStringList.Create;

; SRes := FindFirst (DCN.WatchDir +'/*.*', faAnyFile, SRec);
; while (not Terminated) and (SRes = 0) do begin
; ; if (SRec.Attr <> faDirectory) and
; ; ; ;((DCN.FileExtensions = '') or (Pos (ExtractFileExt (SRec.Name), DCN.FileExtensions) > 0)) then
; ; ; NewDList.Add (SRec.Name);
; ; SRes := FindNext (SRec);
; end;
; SysUtils.FindClose (SRec);

; if (not Terminated) and (not IsInit) then begin
; ; for i := 0 to NewDList.Count - 1 do begin
; ; ; if (Terminated) then Break;
; ; ; if (DCN.CurrentDirList.IndexOf (NewDList ) = -1) then
; ; ; ; NewFiles.Add (NewDList );
; ; end;

; ; for i := 0 to DCN.CurrentDirList.Count - 1 do begin
; ; ; if (Terminated) then Break;
; ; ; if (NewDList.IndexOf (DCN.CurrentDirList ) = -1) then
; ; ; ; DeletedFiles.Add (DCN.CurrentDirList );
; ; end;
; end;

; if (not Terminated) then begin
; ; DCN.CurrentDirList.Assign (NewDList);
; ; DCN.NewFilesList.Assign (NewFiles);
; ; DCN.DeletedFilesList.Assign (DeletedFiles);
; end;

; NewDList.Free;
; NewFiles.Free;
; DeletedFiles.Free;
;
; if (EnableNotify) then
; ; Synchronize (NotifyDCN);
end;

// ------------------------------------------------------------------------------ //
procedure TDiskWatchThreadEx.NotifyDCN;
begin
; DCN.ChangeNotification;
end;

procedure TDiskWatchThreadEx.Execute;
var
; TempArr : array [0..Max_Path-1] of char;
; AHandle : THandle;
begin
; AHandle := FindFirstChangeNotification (StrPCopy (TempArr, DCN.WatchDir),
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; DCN.WatchSubTree,
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; DCN.NotifyFilterW);

; while (not Terminated) and (DCN <> nil) do begin
; ; WaitForSingleObject (AHandle, INFINITE);
; ; //Synchronize (NotifyDCN);
; ; NotifyDCN;
; ; FindNextChangeNotification (AHandle);
; end;

; FindCloseChangeNotification (AHandle);
end;

// ------------------------------------------------------------------------------ //
constructor TDiskChangeNotifyEx.Create (AOwner : TComponent);
begin
; inherited Create (AOwner);
; WatchThread := nil;
; ScanThread := nil;
; FWatchDir := '';
; FWatchSubTree := true;
; FEnabled := false;
; FNotifyFilter := [FILE_NAME, DIR_NAME, ATTRIBUTES, SIZE, LAST_WRITE];
; FFileExts := '';
; FUseTimer := true;
; FTimerDelay := 1000;
; FMaintainedDirList := true;
; Busy := false;

; if (not (csDesigning in ComponentState)) then begin
; ; CurrentDirList := TStringList.Create;
; ; NewFilesList := TStringList.Create;
; ; DeletedFilesList := TStringList.Create;
; ; FTimer := TTimer.Create (nil);
; ; FTimer.Enabled := false;
; ; FTimer.OnTimer := DoNotification;
; end;
end;

destructor TDiskChangeNotifyEx.Destroy;
begin
; if (not (csDesigning in ComponentState)) then begin
; ; Enabled := false;
; ; CurrentDirList.Free;
; ; NewFilesList.Free;
; ; DeletedFilesList.Free;
; ; FTimer.Free;
; end;
; inherited Destroy;
end;

procedure TDiskChangeNotifyEx.SetWatchSubTree (Value : boolean);
begin
; if (FWatchSubTree <> Value) then begin
; ; FWatchSubTree := Value;
; ; if (Enabled) then begin
; ; ; Enabled := false;
; ; ; Enabled := true;
; ; end;
; end;
end;

procedure TDiskChangeNotifyEx.SetEnabled (Value : boolean);
begin
; if (Value) and (csDesigning in ComponentState) then begin
; ; ShowMessage ('Set to true at runtime only');
; ; Exit;
; end;

; if (not (csDesigning in ComponentState)) and (FEnabled <> Value) then begin
; ; FEnabled := Value;
; ; if (FEnabled) then begin
; ; ; if (MaintainedDirList) then begin // Build initial file list
; ; ; ; ScanThread := TScanThread.Create (true);
; ; ; ; ScanThread.DCN := Self;
; ; ; ; ScanThread.FreeOnTerminate := true;
; ; ; ; ScanThread.Resume;
; ; ; ; ScanThread.EnableNotify := false;
; ; ; ; ScanThread.WaitFor;
; ; ; ; ScanThread := nil;
; ; ; end;

; ; ; FTimer.Enabled := false;
; ; ; if (UseTimer) then
; ; ; ; FTimer.Interval := TimerDelay;

; ; ; CreateWatchThread;
; ; end
; ; else begin
; ; ; DestroyWatchThread;
; ; ; if (Assigned (ScanThread)) then
; ; ; ; ScanThread.Terminate;
; ; end;
; end;
end;

procedure TDiskChangeNotifyEx.SetWatchDir (Value : string);
begin
; if (CompareText (FWatchDir, Value) <> 0) then begin
; ; FWatchDir := Value;
; ; if (Enabled) then begin
; ; ; Enabled := false;
; ; ; Enabled := true;
; ; end;
; end;
end;

procedure TDiskChangeNotifyEx.SetNotifyFilter (Filters : TNotifyFiltersEx);
begin
; FNotifyFilter := Filters;
; NotifyFilterW := 0;
; if (FILE_NAME in Filters) ;then NotifyFilterW := NotifyFilterW or FILE_NOTIFY_CHANGE_FILE_NAME;
; if (DIR_NAME in Filters) ; then NotifyFilterW := NotifyFilterW or FILE_NOTIFY_CHANGE_DIR_NAME;
; if (ATTRIBUTES in Filters) then NotifyFilterW := NotifyFilterW or FILE_NOTIFY_CHANGE_ATTRIBUTES;
; if (SIZE in Filters) ; ; ; then NotifyFilterW := NotifyFilterW or FILE_NOTIFY_CHANGE_SIZE;
; if (LAST_WRITE in Filters) then NotifyFilterW := NotifyFilterW or FILE_NOTIFY_CHANGE_LAST_WRITE;
; if (SECURITY in Filters) ; then NotifyFilterW := NotifyFilterW or FILE_NOTIFY_CHANGE_SECURITY;

; if (Enabled) then begin
; ; Enabled := false;
; ; Enabled := true;
; end;
end;

procedure TDiskChangeNotifyEx.CreateWatchThread;
begin
; WatchThread := TDiskWatchThreadEx.Create (true);
; WatchThread.DCN := self;
; WatchThread.FreeOnTerminate := true;
; WatchThread.Resume;
end;

procedure TDiskChangeNotifyEx.DestroyWatchThread;
begin
; if (Assigned (WatchThread)) then begin
; ; WatchThread.Terminate;
; ; WatchThread := nil;
; end;
end;

procedure TDiskChangeNotifyEx.ScanTerminated (Completed : boolean);
begin
; if (Completed) and ((NewFilesList.Count > 0) or (DeletedFilesList.Count > 0)) then
; ; OnFilesChanged (Self, NewFilesList, DeletedFilesList);
; ScanThread := nil;
; Busy := false;
end;

procedure TDiskChangeNotifyEx.ChangeNotification;
begin
; FTimer.Enabled := false;

; if (Assigned (ScanThread)) then begin
; ; ScanThread.Terminate;
; ; ScanThread.WaitFor;
; end;

; if (UseTimer) then
; ; FTimer.Enabled := true
; else
; ; DoNotification (nil);
end;

procedure TDiskChangeNotifyEx.DoNotification (Sender : TObject);
begin
; FTimer.Enabled := false;

; if (MaintainedDirList) then begin
; ; ScanThread := TScanThread.Create (not Assigned (OnFilesChanged));
; ; ScanThread.DCN := Self;
; ; ScanThread.FreeOnTerminate := true;
; ; ScanThread.Resume;
; end;

; if (Assigned (OnDiskChange)) then
; ; OnDiskChange (Self);
end;

end.
 
如果不想太麻烦, 就到 32位深度历险 去找相关控件吧.
vcl.vclxx.com
 
多人接受答案了。
 

Similar threads

回复
0
查看
818
不得闲
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
915
SUNSTONE的Delphi笔记
S
D
回复
0
查看
946
DelphiTeacher的专栏
D
后退
顶部