ファイル時間情報


ファイルタイム

ファイルは作成日時や更新日時、最終アクセス日時などの情報を持っています
ファイルの作成日や最終アクセス日の取得は GetFileTime() 関数で取得できます
BOOL GetFileTime(
	HANDLE hFile , LPFILETIME lpCreationTime ,
	LPFILETIME lpLastAccessTime , LPFILETIME lpLastWriteTime 
);
hFile は時間を取得する GENERIC_READ アクセスを持つファイルハンドルを指定します
lpCreationTime はファイルの作成日時、lpLastAccessTime は最終アクセス時間
lpLastWriteTime が更新日時を格納する FILETIME 構造体へのポインタをそれぞれ指定します
不必要な部分には NULL を指定してください
関数が成功すると 0 以外、失敗すると 0 が返ります

FILETILE 構造体は 1601年1月1日から 100 ナノ秒間隔の数を表す
二つの 32 ビットメンバを持つ 64 ビットの値です
typedef struct _FILETIME {
	DWORD dwLowDateTime;
	DWORD dwHighDateTime;
} FILETIME; 
dwLowDateTime は、ファイル時刻の下位32ビット
dwHighDateTime は、ファイル時刻の上位32ビットを意味します

この 1601 年から 100 ナノ秒単位で表された 64 ビットの数値を
わざわざ数えて現在の時間に直すのは非常に面倒です
当然、Windows はこれを現代時刻に変換する関数をサポートしています

FILETIME をシステム時刻形式にするには FileTimeToSystemTime() を使います
この関数を使えば、SYSTEMTIME 構造体型に整形してくれます
BOOL FileTimeToSystemTime(
	CONST FILETIME *lpFileTime ,
	LPSYSTEMTIME lpSystemTime
);
lpFileTime には GetFileTime() 関数で取得した FILETIME 構造体へのポインタを指定します
lpSystemTime は、lpFileTime をシステム時刻に変換した各値を格納する
SYSTEMTIME 構造体へのポインタを指定します
関数が成功すると 0 以外、失敗すると 0 が返ります

関数が成功すれば、SYSTEMTIME構造体に各データが格納されます
これを用いれば、ファイルの作成日などの時間を詳細に取得できます
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
		PSTR lpCmdLine , int nCmdShow) {
	HANDLE hFile;
	FILETIME ftFileTime;
	SYSTEMTIME stFileTime;
	TCHAR strFileTime[1024];

	hFile = CreateFile(
		lpCmdLine , GENERIC_READ , 0 , NULL ,
		OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL
	);
	if (hFile == INVALID_HANDLE_VALUE) {
		MessageBox(
			NULL , TEXT("ファイルが開けません") ,
			NULL , MB_OK
		);
		return 1;
	}

	GetFileTime(hFile , &ftFileTime , NULL , NULL);
	FileTimeToSystemTime(&ftFileTime , &stFileTime);

	wsprintf(strFileTime , TEXT("%d年 %d月 %d日\n%d時 %d分 %d秒") ,
		stFileTime.wYear , stFileTime.wMonth ,
		stFileTime.wDay , stFileTime.wHour ,
		stFileTime.wMinute , stFileTime.wSecond
	);
	MessageBox(NULL , strFileTime , TEXT("ファイル作成時刻") , MB_OK);

	return 0;
}


このプログラムは、コマンドラインから取得したファイル名からハンドルを生成し
そのファイルハンドルのファイルタイムを FILETIME 構造体に読み込みます
さらに、これを SYSTEMFILE 構造体に変換して、それを表示しています

ファイル時間は、ファイルアイコンを右クリックしポップアップから「プロパティ」を選択し
ファイルのプロパティから確認することもできます
ひょっとすると、システムによってはそこで確認できる時間と
上のプログラムで表示した結果が異なっているかもしれません

なぜ、時間にズレが生じるのかというと
上のプログラムはUTC 世界標準時を表示しているのです
ローカル時間と同じにするには FileTimeToLocalFileTime() 関数を使います
BOOL FileTimeToLocalFileTime(
	CONST FILETIME *lpFileTime ,
	LPFILETIME lpLocalFileTime
);
lpFileTime にはUTCに基くファイル次官が格納されている FILETIME 構造体へのポインタを
lpLocalFileTime には変換後の時間を受ける FILETIME 構造体へのポインタを指定ます
ここに lpFileTime パラメータと同じ値を指定することはできません
関数が成功すると 0 以外、失敗すると 0 を返します
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
		PSTR lpCmdLine , int nCmdShow) {
	HANDLE hFile;
	FILETIME ftFileTime , ftLocalFileTime;
	SYSTEMTIME stFileTime;
	TCHAR strFileTime[1024];

	hFile = CreateFile(
		lpCmdLine , GENERIC_READ , 0 , NULL ,
		OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL
	);
	if (hFile == INVALID_HANDLE_VALUE) {
		MessageBox(
			NULL , TEXT("ファイルが開けません") ,
			NULL , MB_OK
		);
		return 1;
	}

	GetFileTime(hFile , &ftFileTime , NULL , NULL);
	FileTimeToLocalFileTime(&ftFileTime , &ftLocalFileTime);
	FileTimeToSystemTime(&ftLocalFileTime , &stFileTime);

	wsprintf(strFileTime , TEXT("%d年 %d月 %d日\n%d時 %d分 %d秒") ,
		stFileTime.wYear , stFileTime.wMonth ,
		stFileTime.wDay , stFileTime.wHour ,
		stFileTime.wMinute , stFileTime.wSecond
	);
	MessageBox(NULL , strFileTime , TEXT("ファイル作成時刻") , MB_OK);

	return 0;
}
このプログラムは先ほどのプログラムに FileTimeToLocalFileTime() を付加し
ローカルファイル時刻を表示するように変換したものです

因みに、逆にローカル時間を UTC に変換する
LocalFileTimeToFileTime() 関数というものもあります
BOOL LocalFileTimeToFileTime(
	CONST FILETIME *lpLocalFileTime,
	LPFILETIME lpFileTime
);
仕様も FileTimeToLocalFileTime() と同じなので説明不要でしょう
lpLocalFileTime を UTC に変換し lpFileTime に格納します

システム時刻をファイル時刻に変換する SystemTimeToFileTime() もあります
BOOL SystemTimeToFileTime(
	CONST SYSTEMTIME *lpSystemTime,
	LPFILETIME lpFileTime
);
この関数は lpSystemTime をファイル時刻に変換し lpFileTime に格納します
FileTimeToSystemTime() が逆になっただけなので、説明は必要ないでしょう

ファイルの時刻を設定するには SetFileTime() 関数を使います
これを使うことによって、ファイルの作成日などを意図的に書きかえることができます
BOOL SetFileTime(
	HANDLE hFile ,
	CONST FILETIME *lpCreationTime ,
	CONST FILETIME *lpLastAccessTime ,
	CONST FILETIME *lpLastWriteTime
);
hFile にはファイル時刻を変更する GENERIC_WRITE を持ったハンドルを指定します
lpCreationTime は作成時刻、lpLastAccessTime は最終アクセス時刻
lpLastWriteTime は最終アクセス日を FILETIME 構造体でそれぞれ指定します
設定しない部分には NULL を指定することができます
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
		PSTR lpCmdLine , int nCmdShow) {
	HANDLE hFile;
	FILETIME ftFileTime;
	SYSTEMTIME stFileTime;
	TCHAR strFileTime[1024];

	hFile = CreateFile(
		lpCmdLine , GENERIC_WRITE , 0 , NULL ,
		OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL
	);
	if (hFile == INVALID_HANDLE_VALUE) {
		MessageBox(
			NULL , TEXT("ファイルが開けません") ,
			NULL , MB_OK
		);
		return 1;
	}
	GetSystemTime(&stFileTime);
	SystemTimeToFileTime(&stFileTime , &ftFileTime);
	SetFileTime(hFile , &ftFileTime , NULL , NULL);

	return 0;
}
このプログラムはコマンドラインで指定したファイルの作成日を現在時刻に書き換えます


GetFileTime()

BOOL GetFileTime(
	HANDLE hFile , LPFILETIME lpCreationTime ,
	LPFILETIME lpLastAccessTime , LPFILETIME lpLastWriteTime 
);
ファイルの作成日時、更新日時、採集アクセス日時を取得します
取得が不必要な引数には NULL を指定してください

hFile - GENERIC_READ アクセスを持つファイルのハンドルを指定します
lpCreationTime - 作成日時を格納する FILETIME 構造体へのポインタを指定します
lpLastAccessTime - 最終アクセス日時を格納する FILETIME 構造体へのポインタを指定します
lpLastWriteTime - 更新日時を格納する FILETIME 構造体へのポインタを指定します

戻り値 - 成功すると 0 以外、失敗すると 0

FileTimeToSystemTime()

BOOL FileTimeToSystemTime(
	CONST FILETIME *lpFileTime ,
	LPSYSTEMTIME lpSystemTime
);
FILETIME 構造体の日時を SYSTEMTIME 構造体に変換します

liFileTime - 0x8000000000000000 未満の FILETIME 構造体へのポインタを指定します
lpSystemTime - 変換結果を格納する SYSTEMTIME 構造体へのポインタ

戻り値 - 成功すると 0 以外、失敗すると 0

FileTimeToLocalFileTime()

BOOL FileTimeToLocalFileTime(
	CONST FILETIME *lpFileTime ,
	LPFILETIME lpLocalFileTime
);
世界標準時 (UTC) に基づくファイル時間を、ローカルファイル時間に変換します

lpFileTime - UTCに基く時間を格納する FILETIME 構造体へのポインタ
lpLocalFileTime - 変換結果を格納する FILETIME 構造体へのポインタ

戻り値 - 成功すると 0 以外、失敗すると 0

LocalFileTimeToFileTime()

BOOL LocalFileTimeToFileTime(
	CONST FILETIME *lpLocalFileTime,
	LPFILETIME lpFileTime
);
ローカルファイル時間を、世界標準時 (UTC) に基づくファイル時間に変換します

lpLocalFileTime - ローカルファイル時間を格納する FILETIME 構造体へのポインタを指定します
lpFileTime - 変換結果を格納する FILETIME 構造体へのポインタを指定します

戻り値 - 成功すると 0 以外、失敗すると 0

SystemTimeToFileTime()

BOOL SystemTimeToFileTime(
	CONST SYSTEMTIME *lpSystemTime,
	LPFILETIME lpFileTime
);
SYSTEMTIME 構造体の日時を FILETIME 構造体に変換します

lpSystemTime - 変換する SYSTEMTIME 構造体へのポインタを指定します
lpFileTime - 変換結果を受ける FILETIME 構造体へのポインタを指定します

戻り値 - 成功すると 0 以外、失敗すると 0

SetFileTime()

BOOL SetFileTime(
	HANDLE hFile ,
	CONST FILETIME *lpCreationTime ,
	CONST FILETIME *lpLastAccessTime ,
	CONST FILETIME *lpLastWriteTime
);
ファイズの作成日時、更新日時、最終アクセス日時を設定します
設定しない引数には NULL を指定することができます

hFile - GENERIC_WRITE アクセスを持つファイルハンドルを指定します
lpCreationTIle - 作成日時が入ったFILETIME 構造体へのポインタを指定します
lpLastAccessTime - 最終アクセス日時が入った FILETIME 構造体へのポインタを指定します
lpLastWriteTime - 更新日時が入ったFILETIME 構造体へのポインタを指定します

戻り値 - 成功すると 0 以外、失敗すると 0



前のページへ戻る次のページへ