以前の質問で、ファイルが書き換えられたことをアプリケーションがどのように認識できるかという質問がありました。「別のアプリケーションで」を追加する必要がありました。最初に、特定のファイルではなくディレクトリの変更を報告するShellNotifyを試しましたが、何か不足していますか?
ここで、特定のファイルが変更されたかどうかを毎秒チェックするタイマーで FileAge を使用します。それが機能している間、約 13 ミリ秒離れた2 つの変更が検出されます。テスト間隔を 10 秒に変更しても、この動作は持続します。以下のコードはタイマーのコールバックです。
procedure TAMI_Column_Selector.doWork (Sender: TObject);
var new_stamp: TDateTime;
begin
if FileAge (remove_extension (FileName) + '.csv', new_stamp) then
begin
if (new_stamp <> FDateTimeStamp) then
begin
FDateTimeStamp := new_stamp;
FTask.SyncCall (notify_user);
end; // if
end; // if
end; // doWork //
私の質問:
notify_user
上記のコードで が 2 回呼び出される原因は何ですか? ファイルシステムのばかげた間違いまたは奇妙な動作 (たとえば、ファイルを開くときと閉じるときに更新日が設定されるなど)?- ファイルが変更されたかどうかを毎秒チェックするのは、一種の「無駄」に感じます。特定のファイルが変更された場合にのみ通知する ShellNotify のようなものはありますか?
アップデート
David Heffeman の答え (ReadDirectoryChangesW
ポーリングの代わりに使用) は、質問 2 の正しい答えです。ただし、質問 1 で述べたように、(ユーザーの観点から) 1 つの変更中に複数の呼び出しが発生することにもつながります。
ReadDirectoryChangesW
とポーリング方法を比較しました。2 つのファイル (0.5MB と 10 MB) でテスト済み。どちらの場合も、ポーリング メソッドは一貫して 2 回呼び出され、ReadDirectoryChangesW
は数回 (3 ~ 5 回) 呼び出されました。ポーリング方法に戻り、最初のFileAge
変更を無視します。私はそれを引き起こすメカニズムを理解していないので、この動作が一貫していると確信できないことを知っています.