#はじめに
作りは適当なので、参考程度にしてください。例外処理など一切対処していません。
#やりたいこと
- 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();
}
}
}
#関連記事
- (はてなブログ)簡易ログビューワーの作成
- (Qiita)C#で簡易ログビューワーの作成 - とりあえずこれでいいんじゃない?
以上