ファイルに記録する関数を読む
それでは、前回に作成したファイルへログデータを書き込む関数Log_uMsg()をみてみよう。次のような関数を実装して使用した。
Log_uMsg()関数
/*
* MSG.messageを指定したファイルへ追記する関数
*/
void Log_uMsg(LPCWSTR fPath, UINT uMsg)
{
HANDLE hFile;
hFile = CreateFile(
fPath, GENERIC_WRITE, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
);
SetFilePointer(hFile, 0, NULL, FILE_END);
TCHAR buf[1024];
wsprintf(buf, TEXT("message: %d\n"), uMsg);
DWORD dwNoW = 0;
WriteFile(hFile, buf, lstrlen(buf)*sizeof(TCHAR), &dwNoW, NULL);
CloseHandle(hFile);
}
この関数の処理はWindows APIを使ってファイルへの書き込みを行う処理としては基本的なものだ。いろいろと使えるので、基本的な処理を理解しておこう。
まず、ファイルを開いていろいろと使うためにハンドルを用意する。
ファイル操作用のハンドルを用意
HANDLE hFile;
次に、CreateFile()関数を使ってファイルを新規作成またはオープンする。次のような指定でCreateFile()関数を実行すると、ファイルがあればオープン、ファイルがなければ新規作成してオープン、書き込み可能、という状態になる。よく使う組み合わせだ。
書き込み用にファイルオープンまたはファイルの新規作成
hFile = CreateFile(
fPath, GENERIC_WRITE, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
);
CreateFile()関数の第1引数にファイルパスを指定する。この部分を変えれば他のファイルを開くことができる。
次に、ファイルポインタの移動だ。ハンドル経由でアクセスされるファイルは、ファイルの先頭を示す状態になっている。ログデータはファイルの末尾に追加していきたいので、このままでは都合が悪い。ファイルのポインタがファイルの最後を指すようにする必要がある。
この処理はSetFilePointer()関数で行う。これも典型的な処理だ。次のように、ファイルポインタがファイルの末尾を指すようにする。
ファイルポインタをファイルの末尾へ設定する
SetFilePointer(hFile, 0, NULL, FILE_END);
これでファイルポインタがファイルの末尾を指すようになったので、ここから書き込みを行えばファイルの末尾にログが追加されていく状況になるというわけだ。
ファイルへの書き込みにはWriteFile()関数を使用する。まず、この関数に渡す文字列データ(TCHARの配列)を用意する。
TCHARの配列を用意
TCHAR buf[1024];
まず、この配列にファイルへ書き込むデータを用意する。データの用意にはwsprintf()関数を使用する。以下のように、フォーマットを指定してTCHARの配列へ文字列を書き込むことができる。
swprintf()関数でTCHAR配列へ文字列を書き込む
wsprintf(buf, TEXT("message: %d\n"), uMsg);
書き込むログデータ(文字列)が用意できたので、次にWriteFile()関数で書き込みを行う。次のように使う。
WriteFile()関数でファイルへ文字列(ログ)を書き込み
DWORD dwNoW = 0;
WriteFile(hFile, buf, lstrlen(buf)*sizeof(TCHAR), &dwNoW, NULL);
WriteFile()関数の引数に指定しているのはファイルハンドル、ログの書き込まれたTCHAR配列、書き込むデータの長さ、返り値を格納する変数、といったところだ。よく使う方法なので、これも覚えてしまいたい。
処理としては毎回毎回ファイルを開いて閉じるのは無駄ではあるのだが、ここでは基本ということでファイルを閉じておく。次のように、CloseHandle()関数でファイルハンドルを指定して閉じる。
CloseHandle()関数でファイルを閉じる
CloseHandle(hFile);
一連の作業はこれで完了だ。ログデータを書き込む場合は大体こんな感じで処理を行うのが流れの基本となる。