質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.56%

C# FileSystemWachter 1回おきに変更イベント発生

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 189

moto-a

score 12

お世話になります。

環境: C# (.netframework4.6.1)  Windows10, 7

FileSystemWachterで、あるソフトから出力されるファイルの監視をしています。 (ソフトの仕様不明・ソース無)
ファイル変更イベントは発生しますが、ファイル変更イベント時に対象ファイルの読込を行うと次回のファイル変更イベントが発生しません。
ただし、次々回のファイル変更イベントは発生します。(必ず1回おきにファイル変更イベントが発生します)
対象ファイルの読込を行わないと正しく毎回ファイル変更イベントが発生します。
ファイル読込時のソースが外すと問題ありませんので影響していることは間違いないです。

ファイル読込時のソースをどのようにしたらよいでしょうか?

fileWatcher = new System.IO.FileSystemWatcher();
fileWatcher.Path = "c:\hoge";
fileWatcher.InternalBufferSize = 4096;
fileWatcher.IncludeSubdirectories = false;
fileWatcher.NotifyFilter = System.IO.NotifyFilters.Size;
fileWatcher.Filter = "*.csv";
fileWatcher.Changed += watcher_Changed;
fileWatcher.Created += watcher_Created;
fileWatcher.Renamed += watcher_Renamed;
isFileWatch = false;
fileWatcher.EnableRaisingEvents = true;

private void watcher_Changed(System.Object source, System.IO.FileSystemEventArgs e)
{
    //デバッグログ出力

    if (!isFileWatch)
    {
        isFileWatch = true;

        //↓ここから
        using (FileStream fs = new FileStream(e.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
           using (TextReader sr = new StreamReader(fs, Encoding.GetEncoding("UTF-8")))
           {
               String buff = "";
               while ((buff = sr.ReadLine()) != null)
               {
               }
               sr.Close();
           }
           fs.Close();
       }
       //↑ここまでがあるとダメです。


       isFileWatch = false;
    }
}

ログ出力ソフトのテストプログラム

private StreamWriter sw;

public Form1()
{
    InitializeComponent();

    sw = new StreamWriter(File.Open(@"C:\hoge\aaa.csv", FileMode.OpenOrCreate, FileAccess.Write,FileShare.Read),Encoding.Default);
}

private void button1_Click(object sender, EventArgs e)
{
    sw.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));
    sw.Flush();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    sw.Close();
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • dodox86

    2020/01/24 21:59

    StreamWriter.Flush()は恐らくキャッシュ上の書き込みデータをディスクに書き込むだけな為、FileSystemWatcherで監視すべき(あるいは対象の)
    イベントが発生しないのでしょう。SysinternalsのProcessMonitorで当該ファイルのアクセス状況を確認してみると、なにか分かるかもしれません。https://docs.microsoft.com/ja-jp/sysinternals/downloads/procmon

    キャンセル

  • moto-a

    2020/01/24 22:17

    ご回答ありがとうございます。
    Flush()時点ではプロパティのファイルサイズは変更になっていましが、更新日時などは変更されていませんでした。

    キャンセル

  • dodox86

    2020/01/24 22:26

    フィルターが「System.IO.NotifyFilters.Size」でもサイズ変更を検知するのがファイルクローズ後だとすると、書き込み中のFlush()でイベントが発生しなくても仕方がないです。

    キャンセル

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.56%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る