お世話になります。
ファイルのタイムスタンプの更新について、
質問させていただきます。
現在、複数のプロセスから同じファイルに書き込みを行い、
特定のサイズを超えた場合、古いファイルを上書きするという
処理を行っています。
ファイルの新旧を判定する為、CompareFileTime関数を使用しています。
しかし、サイズをチェックする時点ではファイルはオープンされており、
超過した時点でそれを閉じる為、タイムスタンプをチェックする
時点ではファイルは直前でクローズされていてタイムスタンプが
更新されていると思っていたのですが、
エクスプローラから見えるファイルのタイムスタンプは、
書き込みを行っている最中に定期的にしか更新されて居ないように
見えており、CompareFileTime関数がどのタイミングの時間で比較
しているのかわからないような気がしています。
#CompareFileTime関数に渡している情報は直前で
#FileExist関数を使用して取得しています。
タイムスタンプの更新のタイミングに関する情報や
ファイルの新旧を判定する為の処理などで、
詳しい方が居られましたら、ご教授下さいますよう
お願い致します。
#なお現状では、テンポラリのファイル名でファイルを作成し、
#それをリネームして置き換えるという処理などは考えていません。
開発環境:XP Pro Sp2 VC2003SE
実行環境:WindowsServer2003
FileExist関数について書き忘れた為、補足です。
FileExist関数内部で、FindFirstFile関数を使用し
WIN32_FIND_DATA構造体内のデータから
最終書き込み時間を取得しています。
ファイル状態の変更を検知したいのであれば、
FindFirstChangeNotification()
ReadDirectoryChangesW()
SHChangeNotifyRegister()
このあたりを調べてみたらいかがでしょうか
気になった部分だけ書いときますと、
エクスプローラーの画面上での確認では判断できないのではと言う気がします。
Windowsでは画面の描画は忙しい時は後回しにされますから、画面上に表示されない事が
更新されていない事を示しているとは限らないと思います。
実際にはログ出力等で関数内部での判定結果等を確認しないとどのタイミングでというは
判断できないのではないでしょうか。
FUKUさんが提案されている方も検討に入れて見てはどうかと私も思います。
返信が遅くなり申し訳ありません。
>FUKUさん
FindFirstChangeNotification関数なども一考したのですが、
ファイル内容自体はチェックを行う関数を呼び出す上位側で複数プロセスから、
常に更新されているので、毎回通知を受けてしまいそうな気がしています。
また、イベントドリブンとなる為に、その先の処理を通知が来なかった場合など
継続を判断する事が難しく通知自体を別スレッドを生成してから待ち、
ファイルを切り替える様な機構をすべてのファイルに用意する必要が出てくる為、
実装としてかなりややこしそうなので、断念しておりました。。。;
自分で確認するほかになければ、タイミング確認を提示していただいたAPIを
使用して調査しその結果を基にどうするか再考してみようと思います。
>PATIOさん
>エクスプローラーの画面上での確認では判断できないのではと言う気がします。
私も上記の意見と同意なのですが、同僚からタイムスタンプ比較してるけど、
フォルダの画面更新を行っても書き込まれているファイルの更新時間は変わらず、
更新されてないのではないかと突っ込まれ、質問させていただきました。
(実際にタイムスタンプは古くても中身は書かれていますし)
>実際にはログ出力等で関数内部での判定結果等を確認しないと
>どのタイミングでというは判断できないのではないでしょうか。
はやり通知で確認する他は無いということでしょうか。
MSDNなどにも見当たらなかったので。。。
この辺りの扱いはあまりアテにするなということなのでしょうかね。。。;
>> 実際にはログ出力等で関数内部での判定結果等を確認しないと
>> どのタイミングでというは判断できないのではないでしょうか。
> はやり通知で確認する他は無いということでしょうか。
> MSDNなどにも見当たらなかったので。。。
> この辺りの扱いはあまりアテにするなということなのでしょうかね。。。;
というか、判定関数を作られているのでしょうから
実際に動作している状況でログに落として想定どおり動いているかの
確認をすべきではと言う意味です。
OutputDebugStringを使ってモニターソフトで監視と言う手もあるかもしれません。
エクスプローラーに関してはどうしても画面の更新と言う処理が入る関係上、
表示の内容を鵜呑みにするわけにはいかないと思います。
判断している箇所での結果をログに出すのであれば、
画面表示云々の話は関係なくなりますから、内部的な状態も把握できるはず。
しかも内部で忙しく動いているであろう物を動作の最中に確認する為に
エクスプローラーを使うのはどうかと思います。
動作後の状態を確認するのであればOKだと思いますけれど。
こういう確認をしたいのであれば、少なくとも動いているアプリの中に
ログを吐くような仕組みを仕込んで確認しないと駄目でしょう。
返信ありがとうございます。
>実際に動作している状況でログに落として想定どおり動いているかの
>確認をすべきではと言う意味です。
現状で正しく動かない継起があり、
それを確認している段階でエクスプローラでの見え方から
ふと、「タイムスタンプは何時更新されているのか?」
「タイムスタンプの比較は本当にこれで出来ているのか?」
というところに来ています。
なので、最終的な反映タイミングの確認方法として
>>通知で確認する他は無いということでしょうか。
という発言をしました。
言葉足らずで申し訳ないです。
この機能自体がログを出力するものなので、
ログを吐くような仕組みを仕込んではいるのですが、
現状で大量に出力する物から該当のもののみを探すのが
至難の状態となっています。
また、この機能を提供するモジュールはDLLで提供されており、
少し不憫なつくりになっており、このモジュールのみをDebug版に
置き変える事が出来ません。
とりあえず、一度、通知+ログ採取の方法で調べてみようと思うので、
このスレッドを解決とさせていただきます。
FUKUさん、PATIOさんありがとうございました。
ワン