簡易ログビューワーの作成 - タイマー処理版
SkyrimのPapyrusのログは常にファイル更新するわけではないので、タイマー処理でストリームに追記がある場合に、読み取る必要があることが分かりました。
またいくつかの問題もわかりましたので、次の編集を加えます。
- TextBoxではなくRichTextBoxにする
ログファイルの改行コードはLFなので、そのままTextBoxに貼り付けると改行しませんので、RichTextBoxに変更します。
- タイマーを追加する
- タイマーイベントでは前回からファイルサイズ(length)が変更されているかで判断することにします
以下、変更後の全ソースコードです。
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; long pos; long len; 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, richTextBox1); pos = fs.Position; len = fs.Length; timer1.Enabled = true; } private void timer1_Tick(object sender, EventArgs e) { if (fs.Length != len) { fs.Seek(pos, SeekOrigin.Begin); ReadFile(fs, richTextBox1); pos = fs.Position; len = fs.Length; } } static void ReadFile(FileStream fs, RichTextBox 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(); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { fs.Close(); } } }
なお、テスト版として作っているものなので、作りはかなり適当です。
一応、ある程度見込みが出来たので、これからどのようなログビューワーとするかを考えていきたいと思います。