先日、Visual Basic でインクリメントをする方法について、
調べて記事にしました。
その記事の中で、3種類のインクリメントについて、性能測定をしました。
1万回ループさせて、ループ開始前と終了後に、ログファイルに時刻を書きだして、ループにかかった時間を計測していました。
このような形で、年月日と時間、そして好きな任意のメッセージを、書き出すメソッド(関数)を作成して、ログをとっていました。
今回は、折角なので、Visual Basic で、上の画像のようなログファイルを書きだす方法を紹介したいと思います。
まず始めに、コードだけ知りたいよって人のために、コード全体を紹介します。
そのあとに、メソッドの概要、コードの詳細を順に説明していきます。
コード全体の紹介
Private Shared Sub WriteLog(ByVal message As String)
'ログファイルのパス
Dim path As String = My.Application.Info.DirectoryPath.ToString() + "\\run.log"
Using sw As System.IO.StreamWriter = New IO.StreamWriter(path, True, System.Text.Encoding.GetEncoding("UTF-8"))
'現在時刻を取得
Dim dtNow As DateTime = DateTime.Now
'ログに書き込む内容を成形
Dim info_in_log As String = String.Format("{0:yyyy/MM/dd}{1}{2:HH:mm:ss.fff}{3}{4}", dtNow, vbTab, dtNow, vbTab, message)
'ログに書き込みを行なう
sw.WriteLine(info_in_log)
End Using
End Sub
これが、今回紹介するログファイルに日時を書きだすメソッドの全体のコードです。
あとは、ログファイルへの書き出しを行ないたい場所で、
「WriteLog(“計測開始”)」
のように、呼び出すと、ログファイルへ呼び出された瞬間の日時とメッセージを書き出してくれます。
ログファイルが存在しない場合には、新規に作成してくれます。
メソッドの概要
メソッド全体のフローチャート
関数が呼ばれた時点での、時刻を取得して、ファイルに書き込みを行なうので、ストップウォッチののような感覚で、記録をログファイルに残せます。
ログファイルへの書き込みは、1行ずつ行います。
そのため、
という良い点があります。
しかし、
という悪い点もあります。
この2点を、理解して悪い点が気にならない場面で使いましょう。
先日のインクリメントについて、性能測定をしていた時は、次のフローチャートのような感じで、このメソッドを使っていました。
ループの前と後の時刻を記録することで、ループ全体の時間を測定していました。
引数について
このメソッドは、文字列の引数を1つ取ります。
ByVal message As String
変数名は、「message」にしています。
変数名の通り、ログファイルに書き込みたい任意のメッセージを渡すことができます。
私は、「計測開始」や「計測終了」を引数として渡していました。
そうすることで、ログファイルに書き込まれる時間が、何の時間か分かりやすくしていました。
ログファイルに書き込む内容について
このメソッドは、1回呼ばれると、決められた形式の文字列をログファイルに書き込みます。
その形式について、確認していきましょう。
大きく分けて、「年月日」を書き込む部分、「時刻」を書き込む部分、そして、「好きな文字列」を書き込む部分に分けることができます。
年月日や時刻は、このメソッドが呼ばれた瞬間の日付や時刻を書き込みます。
画像の例の場合、2021年6月30日の午前6時28分10秒874に、メソッドに「計測開始」という文字列を渡したということになります。
ログファイルが生成される場所について
ログファイルは、プログラムを実行しているexeファイルと同じ場所に、生成します。
具体的には、次の画像のような場所に生成されます。
画像は、インクリメントの性能測定を終了した後のものです。
各ログファイルが、どの方法のものか分かりやすいように名前を変えました。
本来は、この場所に、run.logという名前のログファイルが生成されます。
コードの説明
今回のコードは、こちらです。
Private Shared Sub WriteLog(ByVal message As String)
'ログファイルのパス
Dim path As String = My.Application.Info.DirectoryPath.ToString() + "\\run.log"
Using sw As System.IO.StreamWriter = New IO.StreamWriter(path, True, System.Text.Encoding.GetEncoding("UTF-8"))
'現在時刻を取得
Dim dtNow As DateTime = DateTime.Now
'ログに書き込む内容を成形
Dim info_in_log As String = String.Format("{0:yyyy/MM/dd}{1}{2:HH:mm:ss.fff}{3}{4}", dtNow, vbTab, dtNow, vbTab, message)
'ログに書き込みを行なう
sw.WriteLine(info_in_log)
End Using
End Sub
ここからは、このコードを細かく切り分けて、何をしているのか説明していきます。
メソッド名と引数
Private Shared Sub WriteLog(ByVal message As String)
メソッドの名前は、WriteLog です。
また、このメソッドは引数として、好きなメッセージを受け取ります。
それを、messageという名前の変数で、受け取ります。
ログファイルのパスの取得
Dim path As String = My.Application.Info.DirectoryPath.ToString() + "\\run.log"
この部分で、ログファイルが置いてある場所を取得しています。
より正確に言うと、アプリケーションが格納されているディレクトリに、「run.log」を結合したものを、パスとして、変数pathに代入しています。
アプリケーションが格納されているパスをメソッドに、直書きすることもできます。
しかし、今回のようにパスを取得させることで、次のようなメリットがあります。
つまり、別のアプリケーションで何かログファイルに書き出しを行ないたくなった時に、
今回のコードをコピペするだけでも、書き出しを行なえるということです。
直書きしてしまうと、毎回パスを書き直す必要が出てきます。
ログファイルへの、書き出す準備をする
Using sw As System.IO.StreamWriter = New IO.StreamWriter(path, True, System.Text.Encoding.GetEncoding("UTF-8"))
ログファイルへの書き出しの準備を行なって、swという変数で利用することができるようにしています。
IO.StreamWriter は、引数が3つあります。
順番に、確認しましょう。
IO.StreamWriterの引数1つ目
1つ目は、書き込みを行なうログファイルの、完全なファイルパスです。
今回のメソッドでは、変数pathに、取得したファイルのパスを格納しています。
そこで、今回はpathを渡しています。
IO.StreamWriterの引数2つ目
2つ目は、データをファイルに追加するか、上書きするのかを決めています。
trueの場合は、データをファイルに追加します。つまり、どんどん書き足していくことになります。
falseの場合は、データでファイルを上書きします。つまり、ファイルに保存されていた内容を削除して、新たにデータを書き込むということになります。
今回は、ログファイルにどんどん、情報を蓄積させたいので、trueを渡しています。
IO.StreamWriterの引数3つ目
3つ目では、文字コードを指定しています。
今回は、UTF-8で、書き込みを行ないます。
現在日時の取得を行なう
Dim dtNow As DateTime = DateTime.Now
この部分で取得した日付や時刻が、ログファイルに書き込まれます。
この短い1行で、年月日や時刻まで取得できるので、非常に便利です。
これを次の文字列の成形で、使用していきます。
ログへ書き出す文字列を成形する
Dim info_in_log As String = String.Format("{0:yyyy/MM/dd}{1}{2:HH:mm:ss.fff}{3}{4}", dtNow, vbTab, dtNow, vbTab, message)
実際に、ログファイルに書き込まれる内容を整えている部分です。
作成した文字列をinfo_in_logという変数に格納しています。
String.formatに引数が多く渡されていますが、第1引数とそれ以外に、大きく分けることができます。
第1引数では、文字列の形式を定めています。
yyyy/MM/ddが年月日の表記、HH:mm:ss.fffが時刻の表記を定めている部分になります。
俗に”ヤマダ方式”なんて呼ばれたりもする、日時のフォーマットの仕方のことです。
第2引数以降で、第1引数に代入するものを定めています。
第1引数の”{}“の場所に、代入するものを決めています。
第1引数に、”{}“が、5個あるので、第2~6引数で、それぞれに代入するものを渡しています。
基本的には、”{}“の位置と、引数の順番は対応しています。
{4}の位置には、変数messageの内容が代入されます。
{1}や{3}に代入される、vbTabは、タブ文字のことです。
ファイルへの書き出しを行なう
sw.WriteLine(info_in_log)
これが、このメソッドの最も重要なログファイルへの書き出しを行なっている部分です。
変数info_in_logの内容が、ログファイルに書き込まれます。
ここまでで説明してきた通り、ログファイルの中身を残したまま、info_in_logの内容が、書き込まれます。
また、ログファイルが存在しなかった場合は、ファイルの作成を行なってくれます。