ファイル変更通知

Windowsでファイル変更通知を取得するには以下の3つの方法があるようだ。

  1. ReadDirectoryChangesW
  2. FindFirstChangeNotification / FindNextChangeNotification
  3. SHChangeNotifyRegister

 1番目のAPIをラップしたクラスがCodeProjectにあってなかなか使いやすい。
http://www.codeproject.com/file/directorychangewatcher.asp
ただ、On_FileRemovedで通知された際には既に削除済みなので、削除されたのがファイルなのかフォルダなのかを区別する事が出来ない。なのでフォルダ用とファイル用に2つインスタンスを用意して対策する必要があると思う。あとshortとlongの名前のどちらが帰ってくるかがわからない仕様なので、監視するアプリでは両方の名前を持っておいたほうが良いようだ。
http://blogs.msdn.com/ericgu/archive/2005/10/07/478396.aspx

また、On_FileAddedの通知が来るのはファイルが作成された時で、ファイルの作成が完了した時では無いので、On_FileAddedの通知が来た時点ではまだファイルサイズ等が正確に取得できない。ReadDirectoryChangesWのcompletion routineを利用して作成の完了が終わってから通知してくれると楽ちんなんだけれど…。とか思っていたら、作成が終わる前に変更通知が来ちゃうんじゃないかな、との事…。
http://www.codeproject.com/file/directorychangewatcher.asp?searchkw=completion&sd=8%2F21%2F2001&ed=11%2F19%2F2005&select=427226&df=100&forumid=1922&fr=170.5#xx427226xx
結局実際に完了したかどうかは自分でチェックするしかないのかも。
http://search.acty-net.ne.jp/mfc_search/archive/2004-2/msg00628.html
あとcompletion routineを利用する場合は、そのroutineの中ですぐ処理を終えて復帰しないと、ファイル変更通知を取りこぼしてしまうらしい。
http://www.codeproject.com/file/directorychangewatcher.asp?searchkw=completion&sd=8%2F21%2F2001&ed=11%2F19%2F2005&select=409686&df=100&forumid=1922&fr=166.5#xx409686xx
そしてReadDirectoryChangesWはWin2000以降なのと、SAMBAが対応していないみたい。
http://www.samba.gr.jp/ml/article/samba-jp/msg13992.html
.NET FrameworkではFileSystemWatcherというのが存在していて、これはReadDirectoryChangesWをラップしてるみたい。
http://msdn.microsoft.com/msdnmag/issues/02/10/CuttingEdge/

 2番目のFindFirstChangeNotificationは使った事は無いけれど、どのファイルが変更されたかまではわからないらしい。あと、なんか細かい問題は色々有りそう。
http://support.microsoft.com/kb/q188321/

 3番目のSHChangeNotifyRegisterはSHChangeNotifyしてくれるプロセスの通知にしか対応が出来ないようだ。便利なSHFileOperationは通知するみたいだけど、たくさんのファイルを処理すると通知のお陰で遅くなるんだろうか?どうでもいいや…。

 ファイル変更通知とは関係が無いけれど、大きいファイルの場合には自前でファイルコピーするのが良いようだ。あとレジストリをいじってIOバッファーのサイズを変えれば自前でやらなくても速くなるみたい。
http://homepage3.nifty.com/m-and-i/freetalk/upload/g2005_5.htm
http://arena.nikkeibp.co.jp/tec/winxp/20050519/112232/