【解決方法】Filesystemwatcher がイベントをトリガーしない (Windows 10、C#)

プログラミングQA


こんにちは、みんな、

別のアプリによって常に開かれている分厚い txt ファイルを監視しようとしています。 私が知る限り、アプリはファイルを開いたままにして、いくつかのものを追加しています。 今でもファイルにアクセスでき、必要なのは読み取り専用だけです。これまでのところ、とても良いです。

私は ファイルシステムウォッチャー 私のファイルを監視するためですが、悲しいことに、設定したフィルターに関係なく、イベントはトリガーされません。 基本を説明する前に、さまざまなフィルターを使用して手動でテストしたことを覚えておいてください。変更を加えるのが私である限り、すべて正常に機能します (メモ帳、メモ帳 ++、単語などを使用)。

問題を解決するためのコードを探しているのではなく、説明を探しています。 私はしばらく .net でのコーディングをやめていましたが、気付いていない何かが変わったのでしょうか? 私の場合、Windowsがファイルへの変更を報告していないように見えます。おそらく、サードパーティのアプリにmitがあるためです。

私は本当に使用する必要はありません ファイルシステムウォッチャー いくつかの回避策を見ることができますが、目的のために設計されたものを使用するのが好きです…アドバイス/ガイダンスは大歓迎です。

AD1 = ファイルのサイズが変化しているのにファイル ウォッチャーが表示しないことを確認できることに言及する価値があるかもしれません。 これらがサードパーティのアプリによって行われている限り、変更に気付かないようです。

AD2 = Windows がロックされたファイルへの変更を報告せず、共有モードで読み取られるように、少し考えてさらにいくつかのテストを行います。 ファイルが閉じられるまで、Windowsエクスプローラーで言及されたファイルを強調表示するまで、Windowsは変更を報告しません。何らかの形でbashに変更を報告させますが、それを解決策とは言えません。 特に、ウィンドウがほぼ数秒ごとにファイルサイズ情報を更新し続けるのを見ることができるので、これはほとんど意味がありません。

AD3 = C++ と ReadDirectoryChanges で同様のアプローチを試みると、同様の結果が得られます。

さらに情報を提供できる場合はお知らせください。

私が試したこと:

疲れ果てたGoogleの調査を含むほとんどすべて。

解決策 1

引用:

Changed イベントは、監視対象のディレクトリ内のファイルまたはディレクトリのサイズ、システム属性、最終書き込み時刻、最終アクセス時刻、またはセキュリティ アクセス許可が変更されたときに発生します。

(FileSystemWatcher.Changed イベント (System.IO) | Microsoft Docs[^])

そのため、書き込み用 (または読み取り/書き込み用) に開かれたファイルは、ファイルが実際に閉じられる (または可能性は低いですが、フラッシュされる可能性がある) まで、変更されたものとして検出されません。
自分で試してみてください:
データを表示するタイマーを設定します。

C#
FileInfo fi = new FileInfo(@"D:\Test Data\AAA.txt");
txtFileInfo.Text = $"{fi.LastAccessTime}|{fi.LastWriteTime}|{fi.CreationTime}";

次に 3 つのボタン:

C#
private FileStream fs = null;
 private void butOpen_Click(object sender, EventArgs e)
     {
     fs = new FileStream(@"D:\Test Data\AAA.txt", FileMode.Open, FileAccess.ReadWrite);
     }

 private void butClose_Click(object sender, EventArgs e)
     {
     if (fs != null)
         {
         fs.Close();
         fs = null;
         }
     }

 private void butChange_Click(object sender, EventArgs e)
     {
     if (fs != null)
         {
         byte[] data = System.Text.Encoding.UTF8.GetBytes(DateTime.Now.ToLongTimeString());
         fs.Write(data, 0, data.Length);
         }
     }

アクセス情報は、ストリームが閉じられるまで変更されません。これは、ファイル データが「途中で変更された」のではなく、内部的に一貫性があることをシステムが確認できる唯一のポイントであるため、理にかなっています。

解決策 2

あなたは、FSW がどのように機能し、何を検出できるかについて推測しています。

アプリケーションがそのデータを一時ファイルに保存し、元のファイルを削除して一時ファイルの名前を変更した場合、これは FSW によって検出されません。 なぜ? FSW は、フォルダーなど、監視対象のスナップショットを作成するためです。

Visual Studio および Office アプリケーションは、これを行うことで有名です。 1 つのスナップショットには、作成日、最終変更日などの特定の日時が含まれるファイルのリストがあります。Office のようにアプリケーションが変更を加えると、次のスナップショットが発生し、ファイル リストとメタデータがそのスナップショットと比較されます。最後のスナップショット。 FSW によると、元のファイルがなくなり、一時ファイルが同じファイル名で置き換えられても、何も変わっていません。

解決策 3

私は使用しなければならないことがわかりました:
watcher.EnableRaisingEvents = true;

以前のコードではこの行を必要としなかったため、これは少し奇妙です。現在、1 つではなく 2 つの変更イベントを取得しています。

コメント

タイトルとURLをコピーしました