Hatena::ブログ(Diary)

primia -log

2009-05-21(Thu)

時刻を取得する - GetFileTime関数

GetFileTime関数を使って指定したファイルの作成日時、最終アクセス日時、最終更新日時を取得します。

GetFileTime

 指定したファイルの作成日時、最終アクセス日時、最終更新日時を取得します。

BOOL WINAPI GetFileTime(
	HANDLE hFile,
	LPFILETIME lpCreationTime,
	LPFILETIME lpLastAccessTime,
	LPFILETIME lpLastWriteTime
);
  1. hFileはCreateFile関数が返すHANDLE型変数です。この関数を呼び出す前にCreateFile関数をGENERIC_READアクセス権付きで実行して成功させる必要があります。
  2. lpCreationTime,lpLastAccessTime,lpLastWriteTimeはFILETIME構造体変数へのポインタです。いずれもNULLにすることが可能で、その場合はそれに該当する時刻は取得しません。

 関数が失敗すると0返し、成功すれば非0を返します。

Example

#include<stdio.h>
#include<windows.h>

BOOL myGetFileTime(TCHAR *filename,
				   LPFILETIME lpC,
				   LPFILETIME lpA,
				   LPFILETIME lpW
				   );

int main(){
	FILETIME ftC, ftA, ftR, ftl;
	SYSTEMTIME st;
	ULARGE_INTEGER ui;

	if(!myGetFileTime(L"ayanami.jpg",
		&ftC,
		&ftA,
		&ftR)){
			perror("File does not exist\n");
			return 0;
	};

	ui.HighPart = ftC.dwHighDateTime;
	ui.LowPart  = ftC.dwLowDateTime;
	printf("作成時刻:1601年1月から%I64d秒後です。\n", ui.QuadPart / 10000000);
	FileTimeToLocalFileTime(&ftC, &ftl);
	FileTimeToSystemTime(&ftl, &st);
	printf("作成日時:%d%d%d%d%d%d%d\n", st.wYear,
		st.wMonth,
		st.wDay,
		st.wHour,
		st.wMinute,
		st.wSecond,
		st.wMilliseconds);
	putchar('\n');

	ui.HighPart = ftA.dwHighDateTime;
	ui.LowPart  = ftA.dwLowDateTime;
	printf("最終アクセス時刻:1601年1月から%I64d秒後です。\n", ui.QuadPart / 10000000);
	FileTimeToLocalFileTime(&ftA, &ftl);
	FileTimeToSystemTime(&ftl, &st);
	printf("最終アクセス日時:%d%d%d%d%d%d%d\n", st.wYear,
		st.wMonth,
		st.wDay,
		st.wHour,
		st.wMinute,
		st.wSecond,
		st.wMilliseconds);
	putchar('\n');

	ui.HighPart = ftR.dwHighDateTime;
	ui.LowPart  = ftR.dwLowDateTime;
	printf("最終更新時刻:1601年1月から%I64d秒後です。\n", ui.QuadPart / 10000000);
	FileTimeToLocalFileTime(&ftR, &ftl);
	FileTimeToSystemTime(&ftl, &st);
	printf("最終更新日時:%d%d%d%d%d%d%d\n", st.wYear,
		st.wMonth,
		st.wDay,
		st.wHour,
		st.wMinute,
		st.wSecond,
		st.wMilliseconds);
	putchar('\n');

	return 0;
}

BOOL myGetFileTime(TCHAR *filename,
				   LPFILETIME lpC,
				   LPFILETIME lpA,
				   LPFILETIME lpW
				   )
{
	HANDLE hFile;

	hFile = CreateFile(filename,
		GENERIC_READ,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		0);

	if(hFile == INVALID_HANDLE_VALUE){
		/* failed to open the file */
		return FALSE;
	}else{
		/* get time */
		GetFileTime(hFile,
			lpC,
			lpA,
			lpW);
	}
	CloseHandle( hFile );
	return TRUE;
};

Explanation

 WinMain関数を使用していませんが、Win32コンソールプロジェクトでVisual Studioコンパイラで実行します。

 プログラムはayanami.jpgファイルの作成日時、最終アクセス日時、最終更新日時を取得して表示します。

 GetFileTime関数は西暦1601年1月1日午前12時からのUTC経過時間をFILETIME構造体に格納します。単位は100ナノ秒です。FILETIME構造体は64ビット整数を表現するために、DWORD型のふたつのメンバで構成されており、ひとつは上位32ビット、ひとつは下位32ビットです。この構造体の時間でなにか計算する場合、ULARGE_INTEGER共用体を使用します。

 つまり、これらを対応するULARGE_INTEGERのメンバーに代入すると、この共用体のULONGLONG型のメンバで算術演算が可能になります。ちなみに代入せず直接キャスト(型変換)しては駄目だそうです。

 注意する点は、GetFileTimeがタイムゾーンを考慮していないところです。したがってFileTimeToLocalFileTimeを呼び出さずにFileTimeToSystemTimeを呼び出すと時差がある地域ではすこしずれた値になってしまいます。

 格納される時間はそれぞれファイルシステムによって分解能が異なります。FATでは作成日時は10ミリ秒単位、更新日時は2秒単位、アクセス日時は1日単位、とのことです。

Result

作成時刻:1601年1月から12887354462秒後です。
作成日時:2009年5月21日13時41分2秒980

最終アクセス時刻:1601年1月から12887355168秒後です。
最終アクセス日時:2009年5月21日13時52分48秒365

最終更新時刻:1601年1月から12887354431秒後です。
最終更新日時:2009年5月21日13時40分31秒15

続行するには何かキーを押してください . . .

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

Connection: close