none
フォルダ内の更新情報の監視について RRS feed

  • 質問

  • いつもお世話になっております。

    Windows 7 Enterprise (64bit) + Visual Studio 2010 Professional でWin32APIで開発しております。
    現在、特定のフォルダを監視し、フォルダ内にファイルが追加されたらそのファイルをネットワーク上にコピーする、というものを作成しようとしています。

    調査をして、以下の手順が見つかりました。

    1.FindFirstChangeNotification + FindNextChangeNotification をつかう
    2.ReadDirectoryChangesW を使う

    ところが、FindFirstChangeNotification 関数 + FindNextChangeNotification 関数は、無限ループ内でリアルタイム監視ができそうなのですが、
    ファイル名を洗い出すことができず、ReadDirectoryChangesW 関数はファイル名など詳細な情報を取得できますが、イベントを待機するわけではな
    いので、リアルタイムでの監視には不向きなのではないか?と思っているのですが、実際にはいかがなものなのでしょうか?

    そもそも、ReadDirectoryChangesW を実行した際に、「変更があった」という判別をする際の「基準」がどこなのかがわからないため、精度の高いリアル
    タイム監視をしたいのですが心細く…

    それとも、FindFirstChangeNotification 関数 + FindNextChangeNotification 関数でイベントが返ってきた直後にReadDirectoryChangesW
    関数を呼び出すことで、リアルタイムで変更ファイル名を取得することができるのでしょうか?

    さらには.NET FrameworkのSystem.IO.FileSystemWatcher クラスというものもあるようなのですが、こちらを使った方が確実なのでしょうか?
    (できれば.NET Frameworkは使いたくないのですが・・・)

    数秒間隔でtsファイルがポコポコ作成されるフォルダを監視し、追加されたtsファイルをサーバ上にコピーしたいと思っています。
    連続した動画ファイルなので、確実にコピーする必要があります。
    (ちなみに、ファイルコピーに関しては、監視スレッドでイベントが上がった際に別スレッドとしてコピー用スレッドを走らせる予定です)

    ご存知の方がいらっしゃいましたらご教示いただけないでしょうか?
    よろしくお願いいたします。

    2011年10月27日 7:13

回答

  • 無駄なコピーを減らすのであれば、別の方法で書き込み完了を検出し、その時点でコピーすることになります。

    例えば、書き込みを行うプロセスが、書き込み完了を通知する、とかですね。FTP も、受けたサーバーは書き込み完了がわかりますから、通知できます。


    1. 監視スレッドが変更のイベントを受け取ったら、FILE_NOTIFY_INFORMATION構造体のActionを確認
      1. FILE_ACTION_ADDEDだった場合、必要情報を渡してチェック・コピースレッドを作成
      2. チェック・コピースレッドを生成後、スレッド終了を待機せずに直ちに待機状態に戻る

    これですが、書き込みに長い時間がかかった場合、同じファイルを対象とする複数のチェック・コピー スレッドが出来ませんか?


    Jitta@わんくま同盟
    • 回答としてマーク どらちん 2011年11月17日 11:28
    2011年11月14日 12:05

すべての返信

  • まず、どのようなロジックになるのかある程度描けていますでしょうか?

    「変更があった」を受け取り、何か処理をしている間にも更に変更発生する可能性があります。ファイルをオープンしたころにはそれは次の変更を含んでいるかもしれません。「「変更があった」という判別をする際の「基準」がどこなのかがわからない」とのことですが、Windows API側とて基準がわからないでしょう。
    # うまく表現できない…。

    「精度の高いリアルタイム監視」とはどれぐらいの精度を想定していますか? nsオーダーでファイルの変更を知りたいのですか? 1秒間もあればCPUは2,000,000,000クロックの処理をするためとても長い時間と感じます。安易にリアルタイムという用語を使わない方がいいです。ついでに言うとコンピューター分野におけるリアルタイムには特定の意味を持ちます。

    tsファイルに書き込まれるたびにこれらのAPIは情報を返してくれるでしょう。アプリケーションが1回のWriteFile()呼び出しで書き込むとは限らず順々に書き足す場合、何度もその通知を受け取ります。ファイルに書き込みが完了したかどうかはOS側では判断できません。通知を受けるたびに律儀にコピーした場合、コピー先がおかしな状態になるかと思います。

    という思考を踏まえると、「基準」すなわちどれをコピーすべきかはアプリケーション側で判断すべきではありませんか?

    # robocopyに適当なオプションをつけて動かせばそれでよかったりしませんか…?

    2011年10月27日 7:49
  • 根本的なことは佐祐理さんがすでに仰っているので、単純に API の話。

    ReadDirectoryChangesW は、同期モードで呼び出した場合、目標のディレクトリ内の変更を受け取るまでブロックします。非同期モードの場合、変更を受け取ったら、OVERLAPPED 構造体の hEvent や ReadDirectoryChangesW に渡したコールバックで通知されます。

    「呼び出した時点までに溜まっていた変更情報を取得する」という関数ではありません。監視を開始する関数です。

    2011年10月27日 8:09
  • 佐祐理さん、HongLiangさん、レスありがとうございます。

    >佐祐理さん
    すみません、説明が不足して申し訳ありませんでした。
    tsファイルは、必ず異なる名前で、別のサーバ(アプライアンス)からFTP転送されてきます(IISのFTP Serverで受けていると聞いています)。
    新たに追加されて物をひたすらファイルサーバ上にコピーをしていきたいのです。

    現在、定期的にVBScriptでフォルダ内のファイルを総なめして、ファイルの最終更新日が所定の日時以降のものをサーバにコピー(サーバ上にすでにあるもの
    は上書き)するというロジックが動いていて、毎回フォルダ内のファイルをなめること等から、今回質問したようなロジックで、追加されたものだけを都度コピーする
    ようにした方が、ディスクアクセスも少なくなり良いのではないか?ということで作成しています。

    精度に関しては、「追加されたTSファイルが漏れることなくコピーされればよい」と思っております。
    おそらくms単位にもならなく、秒単位でtsファイルが作成されるため、「精度が高い」という言い回しは適切ではなかったかもしれません。
    大変失礼しました。

    >HongLiang
    すみません、私がMSDNをきちんと読んでなかったですね、私^^;
    ReadDirectoryChangesW は必ずすぐに値を返すものだと思っていました。

    処理の手動停止も考慮すると、非同期で関数を起動して、OVERLAPPED構造体のイベントハンドルと手動停止シグナル用のイベントハンドルを使って、
    WaitForMultipleObjectsで待機していればよさそうですね!!

    ありがとうございます!!
    明日にでも会社で試してみてご報告させていただきます♪

    2011年10月27日 11:05
  • 懸念に上がっている、書き込み途中(アップロード途中)は考慮しなくてよいと言うことなのでしょうか?
    言及がなかったので気になりました。

    たぶん、アップロード中に何回も更新イベントが発生するはず。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2011年10月27日 13:23
    モデレータ
    • 編集済み Jitta 2011年10月27日 15:53
    2011年10月27日 15:52
  • 現在、定期的にVBScriptでフォルダ内のファイルを総なめして、ファイルの最終更新日が所定の日時以降のものをサーバにコピー(サーバ上にすでにあるもの
    は上書き)するというロジックが動いていて、毎回フォルダ内のファイルをなめること等から、今回質問したようなロジックで、追加されたものだけを都度コピーする
    ようにした方が、ディスクアクセスも少なくなり良いのではないか?ということで作成しています。

    考えればすぐわかることですが、tsファイルが2GBあったとして、2GB全体を読み込まなければ更新日時が判明しない、などということはありません。ファイル名・更新日時やサイズといった情報はファイルデータとは別の場所で管理されています。
    # というか、ファイルデータ内にそういった情報はありません。

    逆に件のAPIを使用してファイルAが追加されたことが判明したとします。プログラムからファイルAをコピーのためにオープンしようとしますが、このときディスク上でファイルAの場所を検索する必要があります。つまり、更新情報がわかっていようとディスクアクセスが減ることはありません。

    ※ただし、イケm^H^H^HVBScriptでも適切に実装されている場合に限る。

    2011年10月28日 1:18
  • Azuleanさん、Jittaさん、佐祐理さん、レスありがとうございます。

    >Azuleanさん
    >懸念に上がっている、書き込み途中(アップロード途中)は考慮しなくてよいと言うことなのでしょうか?
    >言及がなかったので気になりました。

    ここに関しては「どうなるんだろうなぁ?」と気にはしています。
    ある程度作れたらイベント除いてみようと思っています。

    >Jittaさん
    SyncFramework、こんなのあるんですね、知りませんでした。
    ちょっと調べてみたいと思います。

    >佐祐理さん
    実は、いま実装されているスクリプトは、「フォルダ内のすべてのファイルをGetFileメソッドで取得し、最終更新日を一つ一つ確認して所定の期間内に更新さ
    れたものをネットワーク上にコピーする」という力技?を、1分間隔くらいの短い周期で行っています。
    コピー後も数日はデータが残るため、ファイル数がかなり多く、リアルタイムに更新されたファイル情報だけを取得することで、フォルダ内にあるすべてのファイ
    ルを一つずつ確認するのはどうかと思い投稿した次第です。

    ファイルの更新間隔が数秒単位であることと、一つ一つのファイルサイズがそこまで大きくない(大きくても3MB強)なので、今回の方法でサーバに対するディ
    スクアクセスを減らしたりできるのかな?と思っていたのですが、あまり意味がないんですかね・・・

    上司に「とりあえず作って見せろ」といわれているので、作るだけ作って比較してみます!!

    2011年10月28日 3:27
  • 「ディスクアクセスも少なくなり良いのではないか?」ということですが、ディスク アクセスが多いことで、何か障害が出ている(予想されている)のでしょうか。「調べる」プロセスによって、大元のコピーが阻害されるかもしれない、という懸念でしたら、FILE_IO_PRIORITY_HINT_INFO 構造体でプライオリティを下げることが出来ます。済みません、説明のページを失念してしまいました。検索結果で「紹介」とでている項目が、ワード ドキュメントですが、説明をしているドキュメントです。Windows Vista、Windows Server 2008 以降の機能です。

    「ここに関しては「どうなるんだろうなぁ?」と気にはしています。」ということですが、佐祐理さんの投稿にあるように、それらの関数では書き込みが終わったことを検出できません。書き込み中でもイベントが上がってきます。Process Monitor というツールで、プロセスがファイルを閉じたことがわかるのですが、「how to know when file is closed」で検索すると、ファイル ドライバを作っている様です。興味があれば bing でこの検索キーで検索してみてください。20件以内に「FileMon はどうやって知るんだ?」という英語の質問が上がっています。


    Jitta@わんくま同盟
    2011年11月2日 13:10
  • お話を聞いているとあまり精度の高い話をしているというわけではないように感じました。

    多分、現状の方法で行なっていたとしてもファイルを書き込み中にコピーしようとするケースはありそうです。
    現在の方法で問題になっていないのであれば、書き込み中のファイルがコピーされておかしな状態のファイルが
    できたとしても、最終的に上書きされてまともな状態になればそれで良しという事なのではないかと思いました。

    実際の話、そういう部分についての説明が無いと何処までの厳格性を要求されているのかがわかりません。
    上記のように過渡的な状態を許すのか許さないのかで話はかなり変わってきます。
    その時点のフォルダ内のスナップショットが取れれば良い(その時点で中途半端な内容が混ざっていてもOK)なら
    話はかなり単純になりそうです。


    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    • 編集済み PATIO 2011年11月4日 3:01
    2011年11月4日 3:00
  • Jittaさん、PATIOさん、レスありがとうございます。

    Jittaさん
    >「ディスクアクセスも少なくなり良いのではないか?」ということですが、ディスク アクセスが多いことで、何か障害が出ている(予想されている)のでしょうか?
    障害というよりもディスクアクセスが増えることによるパフォーマンスの低下を気にしています。
    このアプリを実装するサーバは、インターネット公開用のストリーミングサーバです。

    約10秒ごとに1つのtsファイルがFTPでこのサーバに送られてきて、一定時間が経過すると削除されます。
    また、ストリーミングとは別にVOD用に保管する別のストレージがあり、VOD用に長期に保存が必要なtsファイルおよびm3u8ファイルが保存されており、VOD閲覧者はそこにあるファイルから動画を閲覧する形になります。

    先述したとおり、現在は「フォルダ内のすべてのファイルをGetFileメソッドで取得し、最終更新日を一つ一つ確認して所定の期間内に更新されたものをネットワーク上にコピーする」という処理を短い周期で行っています。
    この時に、保険もかねて過去数時間分のtsファイルを対象としていて、対象ファイルはコピー先にあっても上書きする仕組みになっています。
    そのため、ストリーミングサーバがこまめに1000個以上のファイルをコピーコピーしていることになり、これがストリーミングサーバのレスポンスの低下につながっている可能性があると、担当が疑っており、今回のようなプログラムにリプレイスすることで改善するかを確認するためにも作成しなければならない状況なのです。

    >Jittaさん、PATIOさん
    ファイルのコピーに関しては、対象ファイルを「GENERIC_WRITE」でCreateFile関数を使って開こうとすると、ファイルのコピーが完了するまではファイルのオープンに失敗するみたいです。
          CreateFile(pwcFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    これを活用し、開けるようになるまで100ミリ秒Sleep⇒確認の繰り返しを行うことで、何とかなりそうな感じです。

    後は、この動作をFTP転送中やストリーミング開いている最中などに行った場合に問題が起きなければ、ファイル転送中であるかどうかの確認はこの方法で行おうと思っております。

    上司からの指令なので、できることはすべてやってもなければならないのでかなりつらいのですが、頑張ってみます☆
    他のタスクでやや進捗が遅れておりますが、結果などは追ってご報告したいと思います。

    引き続き何か参考になる情報などがございましたら、ご教示いただけると幸いです。

    2011年11月4日 9:46
  • 直近に更新したファイルなら、実際にはキャッシュにアクセスするため、そうディスク I/O を上げないかもしれません。

    WMI に、ディスク I/O について報告するものがあります。
    http://www.wmifun.net/library/win32_perfrawdata_perfdisk_physicaldisk.html

    これを使ったガジェットがあるのだけれど、URL を失念...数値を表示させるくらいならそう難しくないので、この数値を見るようなツールを作って、アクセスしてみてください。あるいは、「コンピュータの管理」で「パフォーマンス モニター」に、「Phisycal Disk : Disk Transfers」を追加します。更新日時を調べるくらいなら、実際のディスク転送は行われていないかもしれません。これと、先に紹介したプロセス モニターでファイルだけを監視対象にして動作させてみるといいでしょう。ひっきりなしにファイルにアクセスしているのに、物理ディスクからの転送はほとんど行われていないことがわかるはずです。


    Jitta@わんくま同盟
    2011年11月6日 6:52
  • Jittaさん

    レスありがとうございます。
    上の意見としては現在動作しているスクリプトで

    1.フォルダ内のファイルの更新日時をチェック
    2.現在時刻-定数(x分)より最近に更新されたファイルをファイルサーバにコピー

    というように動作させているのですが、できるだけすぐに作成されたファイルをファイルサーバにコピーさせたいらしく、30秒に1回このタスクが動作して
    います(あえて上書きコピーするように指示されています)。

    そうすると、重複ファイルを何度も立て続けにコピーすることになり、ディスクアクセスが頻繁に行われることを懸念し、常駐して変更があったときにそれ
    だけをコピーする形のプログラムができないか?それによりディスクIOが減らせないか?というのが上司からの指示なもので…

    更新日時を調べているだけなら、おっしゃる通り大したアクセスはしていないと思うのですが、そのあとの処理を気にしているみたいで…

    あれから進捗がなくて申し訳ありませんが、進捗がありましたらまた書き込みさせていただきます。

    2011年11月8日 2:35
  • やはり気になるのですが、「ディスクアクセスが頻繁に行われること」で、何が問題になるのでしょうか。例えば「ディスクの寿命が縮む」とか、「他の必要なアクセスが阻害される」とか。これによって、対策の建て方が変わります。


    本題。コードを書くより先に、設計が必要ですね。

    例えば、ChangeNotification を受けるだけのスレッド、判断をするスレッド、コピーをするだけのスレッドを作ります。変更リストと、コピー バッファを作ります。通知を受けるスレッドは、ひたすら変更リストに追加していきます。判断をするスレッドは、定期的に変更リストに重複がないか調べ、重複していないアイテムをコピー バッファに押し込んでいきます。コピーするスレッドは、バッファが空でなければコピー処理を行います。・・・こんな感じ?


    Jitta@わんくま同盟
    2011年11月8日 15:53
  • Jittaさん

    レスありがとうございます。

    >例えば「ディスクの寿命が縮む」とか、「他の必要なアクセスが阻害される」とか。
    結論から言うと、後者につながる要因を少しでも減らしたいのです。

    一部以前記載した項目と重複しますが、ご了承ください。

    このファイル(コピー元)が保存されているサーバは、インターネットから外部(不特定多数誰でも)アクセスできるストリーミングサーバです。
    約10秒ごとに1つのtsファイルが、エンコーダアプライアンスからFTPで転送されてきます。

    インターネットを利用しているユーザはこのストリーミングデータを参照しているわけです。

    で、このtsファイルを使って過去のストリーミングを番組ごとなどに区切ってVODとして公開するため、別のサーバへコピーを行っているんです。

    このコピーをする処理を無駄なファイルの読み書きを最小限にすることで、外部公開サービスに可能な限り負荷を軽減したい、というのが会社の意向のようです。

    >コードを書くより先に、設計が必要ですね。
    こちらに関しては、すでにChangeNotification を受けるだけのスレッドは用意しています。
    そこから先のスレッドはひとつのスレッドとして用意し、ChangeNotification がイベントを返すたびにそのスレッドに丸投げしています(CreateProcessをしてすぐにCloseHandleしてます)。
    チェック・コピー用のスレッドは、必要な処理が終わったら、ChangeNotification を受けるだけのスレッドから受け取ったバッファなどを解放して終了するようにしています。

    このつくりだとあまりよくないですか?
    (以前別の常駐可動アプリで、このようにスレッドを放り投げしてイベント(TCPパケットの受信)漏れをなくせたので、それを参考に作ってみたのですが)

    2011年11月8日 23:50
  • 細かいことを言うと別質問ですよね。どらちんさんの当初の質問は「変更内容の監視方法」でありそれに対して「まず、どのようなロジックになるのかある程度描けていますでしょうか?」と返しました。結局この辺りがしっかり描けておらず、監視方法には辿り着けていないのでは…?

    ファイル一覧や各ファイルのサイズ・更新日時などを取得はファイルアクセスを伴わない、と既に回答しています。「無駄なファイル読み書き」となるとあとは同じファイルを何度もコピーしていないか、という程度では?
    # 書き込み途中のファイルをコピーしたためにサイズ不足で、再度コピーすることになる、とかも無駄ですよね。

    2011年11月9日 0:24
  • 佐祐理さん、レスありがとうございます。

    >細かいことを言うと別質問ですよね。どらちんさんの当初の質問は「変更内容の監視方法」でありそれに対して「まず、どのようなロジックになるのかある程度描けていますでしょうか?」と返しました。結局この辺りがしっかり描けておらず、監視方法には辿り着けていないのでは…?

    私が現在描いている監視方法は、以下の通りです。
    (ある程度作成しているのですが、ftp転送やIIS公開フォルダ上を監視できていないなどあり、確定ではありませんが…)

    ・メインスレッドが監視スレッドを作成
    ・監視スレッドは「ReadDirectoryChangesW」関数でディレクトリ内を監視
      ※すみません、Jittaさんとのやり取りでは「ChangeNotification 」と記載して今したが私の大ボケでした^^;
    ・監視スレッドが変更のイベントを受け取ったら、FILE_NOTIFY_INFORMATION構造体のActionを確認
      ⇒FILE_ACTION_ADDEDだった場合、必要情報を渡してチェック・コピースレッドを作成
      ⇒チェック・コピースレッドを生成後、スレッド終了を待機せずに直ちに待機状態に戻る
    ・チェック・コピースレッドは、CreateFile関数で書込みモードでファイルを開けるかで書き込み中かを判断
      ※ファイルコピー時はこれで問題なかったですが、FTP転送時はどうかは未検証(ここで仕事が止まってます)
      ⇒書込み中だった場合は一定時間待機して再チェック
      ⇒書込み中でないと判断されたら、対象ファイルのみをコピー
      ⇒コピーが終わったら監視スレッドから受け取った情報のうち、解放する必要があるバッファを解放してスレッド終了

    このように考えて、プログラムもとりあえず上記で動くように作っています。
    これでは構成が描けていないのでしょうか・・・?

    >ファイル一覧や各ファイルのサイズ・更新日時などを取得はファイルアクセスを伴わない、と既に回答しています。>「無駄なファイル読み書き」となるとあとは同じファイルを何度もコピーしていないか、という程度では?

    過去のやり取りを見ていただけばわかると思いますが、その無駄なファイルの読み書きを避けるために、フォルダを監視して追加されたファイルだけをコピーしていくプログラムを作成しようと考えているのですが…
    (現在のファイルコピーのタスクは重複ファイルも気にせず大量に上書きしているので、それを改善するために新しいプログラムを作ってみているのです)

    何か私の認識に誤りでもあるのでしょうか?
    不勉強かつ認識が足りておらず大変申し訳ありませんが、ご指摘いただけると幸いです^^;

    2011年11月9日 8:26
  • 過去のやり取りを見ていただけばわかると思いますが、その無駄なファイルの読み書きを避けるために、フォルダを監視して追加されたファイルだけをコピーしていくプログラムを作成しようと考えているのですが…
    (現在のファイルコピーのタスクは重複ファイルも気にせず大量に上書きしているので、それを改善するために新しいプログラムを作ってみているのです)

    この代替として

    ・メインスレッドが監視スレッドを作成
    ・監視スレッドは「ReadDirectoryChangesW」関数でディレクトリ内を監視
    ※すみません、Jittaさんとのやり取りでは「ChangeNotification 」と記載して今したが私の大ボケでした^^;
    ・監視スレッドが変更のイベントを受け取ったら、FILE_NOTIFY_INFORMATION構造体のActionを確認
    ⇒FILE_ACTION_ADDEDだった場合、必要情報を渡してチェック・コピースレッドを作成
    ⇒チェック・コピースレッドを生成後、スレッド終了を待機せずに直ちに待機状態に戻る
    ・チェック・コピースレッドは、CreateFile関数で書込みモードでファイルを開けるかで書き込み中かを判断
    ※ファイルコピー時はこれで問題なかったですが、FTP転送時はどうかは未検証(ここで仕事が止まってます)
    ⇒書込み中だった場合は一定時間待機して再チェック
    ⇒書込み中でないと判断されたら、対象ファイルのみをコピー
    ⇒コピーが終わったら監視スレッドから受け取った情報のうち、解放する必要があるバッファを解放してスレッド終了

    というロジックを考えているんですよね?

    最初から「ファイルに書き込みが完了したかどうかはOS側では判断できません」と指摘しています。
    # ChangeNotificationもReadDirectoryChangesWも書き込みがあったことはわかりますが、それで完了したかはわからない。

    無駄なコピーを減らすのであれば、別の方法で書き込み完了を検出し、その時点でコピーすることになります。となれば、ChangeNotificationもReadDirectoryChangesWも使う必要はないという方向に進むと思っていました。

    2011年11月10日 0:53
  • 佐祐理さん、レスありがとうございます。

    >最初から「ファイルに書き込みが完了したかどうかはOS側では判断できません」と指摘しています。
    ># ChangeNotificationもReadDirectoryChangesWも書き込みがあったことはわかりますが、それで完了し
    >たかはわからない。

    ここは理解しています。
    で、記載されているCreateFile関数で書き込みモードでファイルを開いてみると、単純なファイルコピーでしかチェックしていませんが、ファイルのコピーが完了するまではCreateFile関数が失敗しました。

    FTPでファイル転送時も同様な形でチェックできれば、かなり強引ですがCreateFile関数を使ってやってみよう、と行き着いたのが上記ロジックです。

    排他モードで開ければ確実なんですけど、ストリーミングとして公開している以上、それはできないですからね…
    (排他モードでファイルを開くことでファイルが別プログラムでアクセス中かを判断するプログラムはMSのサイトにサンプルがあったので、そいつを応用して、今回の用途限定で使えないかと思っています)

    あくまでも、ReadDirectoryChangesWでは、「新しいファイルがフォルダ内にできた」事だけを待機し、CreateFileを使って書き込み中かを判断できたらな~という形で考えています。

    最初にアドバイスいただいた時点で「ReadDirectoryChangesW」でファイルが書き込み中かを判断しようとは一切考えておりません。

    2011年11月10日 1:57
  • 無駄なコピーを減らすのであれば、別の方法で書き込み完了を検出し、その時点でコピーすることになります。

    例えば、書き込みを行うプロセスが、書き込み完了を通知する、とかですね。FTP も、受けたサーバーは書き込み完了がわかりますから、通知できます。


    1. 監視スレッドが変更のイベントを受け取ったら、FILE_NOTIFY_INFORMATION構造体のActionを確認
      1. FILE_ACTION_ADDEDだった場合、必要情報を渡してチェック・コピースレッドを作成
      2. チェック・コピースレッドを生成後、スレッド終了を待機せずに直ちに待機状態に戻る

    これですが、書き込みに長い時間がかかった場合、同じファイルを対象とする複数のチェック・コピー スレッドが出来ませんか?


    Jitta@わんくま同盟
    • 回答としてマーク どらちん 2011年11月17日 11:28
    2011年11月14日 12:05
  • Jittaさん

    レス、ありがとうございます。

    >例えば、書き込みを行うプロセスが、書き込み完了を通知する、とかですね。FTP も、受けたサーバーは書き込み完了がわかりますから、通知できます。

    そうなんですね。
    IISのFTPサービスからの書き込み完了の通知を受け取れるか調べてみます。

    >これですが、書き込みに長い時間がかかった場合、同じファイルを対象とする複数のチェック・コピー スレッドが出来ませんか?

    FTPではまた未検証なのですが、通常のファイルコピーに関しては、GBクラスのファイルをコピーした際にも、コピーが完了するまでに同じファイルに対するスレッドが生成されることはありませんでした。

    FTP転送に関しては今週中に検証がはじめられそうなので、結果が出たらまたご報告させていただきます。

    2011年11月16日 2:03
  • アドバイスをいただいたみま皆様。
    さまざまなご指摘・アドバイスありがとうございます。

    CreateFileを使った書き込み状態の確認ですが、IISのFTPで、ファイルコピー同様うまく稼働しました。
    (ファイルのコピーが完了するまで、しっかりと待機してくれます)

    今回は、このロジックを使って作成してみたいと思います。

    ありがとうございました!!

    2011年11月17日 11:30