16

選択したフォルダーで *.log ファイルをリッスンするアプリがあります。使用しFileSystemWatcherました。

しかし問題がある。そのファイルの作成を担当する他のアプリは、次の手順を実行します。

  1. *.gz ファイルを作成する
  2. txtファイルに解凍します(ランダムなファイル名)
  3. *.txt 名を *.log 拡張子を持つ適切な名前に変更します。

そして、私はこの行動を変えることはできません。

したがってFileSystemWatcher、*.gz および *.txt ファイル用に 2 つの s を作成しました。なんで?このアプリは gz ファイルを展開しない場合があり、txt ファイルの名前を最終的な *.log ファイルに変更しない場合があるためです。

FileSystemWatcher2txt ファイルをキャッチし、(ほとんどの場合、次の 1000 ミリ秒でログに記録するために名前が変更されます) txt ファイルが存在するかどうかを確認するためにしばらく待つ必要があります (存在しない場合は、最終的な *.log ファイルに名前が変更されるようです)。

Thread.Sleep()問題は、 UI のフリーズを防止 せずにファイルが存在するかどうかを確認する方法です。

明確でない場合は、より適切に説明しようとします。これは複雑な問題だと思います。

いくつかのコードサンプル:

gz ファイルのウォッチャー:

private void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
   //this is for gz files in case if gz file is not unpacked automatically by other app
   //I need to wait and check if gz was unpacked, if not, unpack it by myself,
   //then txt watcher will catch that
   Thread.Sleep(5000);
   if (File.Exists(e.FullPath))
   {
      try
      {
         byte[] dataBuffer = new byte[4096];
         using (System.IO.Stream fs = new FileStream(e.FullPath, 
                                                     FileMode.Open, 
                                                     FileAccess.Read))
         {
            using (GZipInputStream gzipStream = new GZipInputStream(fs))
            {                            
               string fnOut = Path.Combine(path_to_watcher, 
                                           Path.GetFileNameWithoutExtension(e.FullPath));

               using (FileStream fsOut = File.Create(fnOut))
               {
                  StreamUtils.Copy(gzipStream, fsOut, dataBuffer);
               }                            
            }
         }
      }
      catch { //Ignore }
   }
}

txt ファイルのウォッチャー:

private void fileSystemWatcher2_Created(object sender, FileSystemEventArgs e)
{
   //this is for txt file
   Thread.Sleep(3500);
   if (File.Exists(e.FullPath))
   {
      //make my actions
   }
   else
   {
      //make my actions
   }
}
4

4 に答える 4

16

実際には FileSystemWatcher Created イベントが .NET 自体によって別のスレッドで呼び出されます.. したがって、基本的に何もする必要はありません。あなたのコードはそのままでOKです。

証拠は次のとおりです。

class Program
{
    static void Main(string[] args)
    {
        FileSystemWatcher fw = new FileSystemWatcher(@"C:\temp");
        fw.Created += fileSystemWatcher_Created;

        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

        fw.EnableRaisingEvents = true;

        Console.ReadLine();
    }

    static void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    }
}
于 2013-02-14T04:03:41.620 に答える
3

BackGroundWorkerを使用してファイル システムを監視し、UI のフリーズを回避できます。

于 2013-02-11T16:36:29.847 に答える