HUSKING - kotteri

技術系Note

【C#】Windowsでの tail -f 的なことをしたかった

ので、簡易的なものを作ってみた

string file = "c:\aaa.txt";
FileInfo fi = new FileInfo(file);
if (!fi.Exists)
{
    Console.WriteLine(string.Format("指定されたファイル({0})が存在しません", file));
}
using (FileStream fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    bool run = true;
    // リードポインタをファイル最後尾にもってくる
    fs.Position = fs.Length;
    using (FileSystemWatcher fw = new FileSystemWatcher())
    {
        // 監視するフォルダ
        fw.Path = fi.DirectoryName;
        // 監視フィルタ設定
        fw.Filter = fi.Name;
        // 出力イベント用メソッド
        Action<Object, FileSystemEventArgs> ReadText = (sender, e) =>
        {
            fi.Refresh();
            // ファイルの追加分を読み込む
            long diff = fs.Length - fs.Position;
            if (diff < 1)
            {
                return;
            }
            byte[] bytes = new byte[diff];
            fs.Read(bytes, 0, bytes.Length);
            // 読み込んだ文字列を行区切りに分割する
            string[] lines = Encoding.GetEncoding("utf-8").GetString(bytes).Split('\n');
            // コンソールに出力
            foreach (string line in lines)
            {
                if (!line.Equals("\r"))
                {
                    Console.WriteLine(line);
                }
            }
        };
        // 停止イベント用メソッド
        Action<Object, ConsoleCancelEventArgs> EventStop = (sender, e) =>
        {
            // ウォッチ停止
            fw.EnableRaisingEvents = false;
        };
        // ctrl + c 時処理
        Console.CancelKeyPress += new ConsoleCancelEventHandler(EventStop);
        // イベント検出時処理
        fw.Changed += new FileSystemEventHandler(ReadText);
        // ウォッチ開始
        fw.EnableRaisingEvents = true;
        // ループ処理
        while (run)
        {
            string input = Console.ReadLine();
            if (!string.IsNullOrEmpty(input) && input.Equals("quit"))
            {
                fw.EnableRaisingEvents = false;
                run = false;
            }
        }
    }
}
Console.WriteLine("\n\nStopped...");

aaa.txtに行が追加されると、自動でコンソールに出力される。
終了する場合には、"quit"と入力する。