LoginSignup
3
8

More than 5 years have passed since last update.

C#で簡易ログビューワーの作成 - ファイル監視で行う

Last updated at Posted at 2016-12-22

はじめに

作りは適当なので、参考程度にしてください。例外処理など一切対処していません。

やりたいこと

  • TextBoxにて指定のテキストファイルを読み込み、その後ファイルの変更があったら続きをTextBoxに追記する
  • ファイルシステムウォッチャー(FileSystemWatcher)を利用する
  • ファイル読込はByte形式で、指定バイト数を繰り返して読むことにする

ポイント

ファイルシステムウォッチャーでファイル監視する

String fileName = ""; //任意のファイルパス

//ファイルを読込専用、他プロセスからの読書き可能として開き、読込んで読込み位置を取得する
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

//指定のファイルのみ更新された際に、非同期にイベントを呼出す
FileSystemWatcher fsw = new FileSystemWatcher();
fsw.Path = System.IO.Path.GetDirectoryName(fileName);
fsw.Filter = System.IO.Path.GetFileName(fileName);
fsw.NotifyFilter = NotifyFilters.LastWrite;
fsw.Changed += new FileSystemEventHandler(fsw_Changed); 
fsw.SynchronizingObject = this;
fsw.EnableRaisingEvents = true;

ソースコード全体

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace SimpleLogViewer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        FileStream fs;
        FileSystemWatcher fsw;
        long pos;
        private void Form1_Load(object sender, EventArgs e)
        {
            //オープンファイルダイアログを表示
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.ShowDialog();

            //TODO:ファイルが選ばれなかった場合などの処理が必要

            //ファイルを読込専用、他プロセスからの読書き可能として開き、読込んで読込み位置を取得する
            fs = new FileStream(dlg.FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            ReadFile(fs, textBox1);
            pos = fs.Position;

            //指定のファイルのみ、更新された際に非同期にイベントを呼出す
            fsw = new FileSystemWatcher();
            fsw.Path = Path.GetDirectoryName(dlg.FileName);
            fsw.Filter = Path.GetFileName(dlg.FileName);
            fsw.NotifyFilter = NotifyFilters.LastWrite;
            fsw.Changed += new FileSystemEventHandler(fsw_Changed);
            fsw.SynchronizingObject = this;
            fsw.EnableRaisingEvents = true;
        }

        static void ReadFile(FileStream fs, TextBox tb)
        {
            //ファイルを一時的に読み込むバイト型配列を作成する
            byte[] bs = new byte[0x1000];
            //ファイルをすべて読み込む
            for (;;)
            {
                //ファイルの一部を読み込む
                int readSize = fs.Read(bs, 0, bs.Length);
                //ファイルをすべて読み込んだときは終了する
                if (readSize == 0)
                    break;
                //部分的に読み込んだデータを使用したコードをここに記述する
                tb.Text += System.Text.Encoding.GetEncoding(932).GetString(bs);
            }
            //カーソルを行末に移動して、スクロールさせる
            tb.SelectionStart = tb.Text.Length;
            tb.ScrollToCaret();
        }

        void fsw_Changed(object sender, FileSystemEventArgs e)
        {
            //ファイルの先頭から指定した位置までストリーム内の読込み位置を変更し、追加分のデータを読込んで、読込み位置を最後の位置にする
            fs.Seek(pos, SeekOrigin.Begin);
            ReadFile(fs, textBox1);
            pos = fs.Position;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            fs.Close();
            fsw.EnableRaisingEvents = false;
            fsw.Dispose();
        }
    }
}

関連記事

以上

3
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
8