〜 ファイル 〜
ファイルのタイムスタンプを取得 (要KERNEL32.DLL)

ファイルの作成日時や更新日時等のタイムスタンプは、API関数GetFileTimeで取得できますが、
1601年から100ナノ秒単位で表された64ビット値で取得されます。
取得日時がいつになるかを計算するのもアリですが、64ビットのファイル時刻をシステム時刻に変換する
API関数FileTimeToSystemTimeを使うと楽です。
まず、API関数GetFileTimeでタイムスタンプを取得する必要があるわけですが、
どのファイルを取得するかを指定するものが、パス文字列ではなくハンドルを指定する必要があるため、
HSPから使用するには、API関数GetFileTimeを使用する前にパス文字列をハンドルに変換する
API関数CreateFileと使用後に解放するCloseHandleを使用する必要があります。
API関数CreateFileの第1引数はファイルパス文字列を格納した変数ポインタです。
第2引数は以下のアクセスタイプのいずれかを指定します。
0x00000000存在確認等の問い合わせのみ
GENERIC_WRITE0x40000000書込アクセス
GENERIC_READ0x80000000読込アクセス
今回はハンドルを取得するだけなので問い合わせのみ(=0x00000000)で良いでしょう。 第3引数は開いた後に他からのアクセスを許可するか否か共有設定を指定します。
0x0000共有しない。
FILE_SHARE_READ0x0001読取アクセスを許可
FILE_SHARE_WRITE0x0002書込アクセスを許可
FILE_SHARE_DELETE0x0004削除アクセスを許可
他ファイルと連携するわけではありませんので(=0x0000)で良いですが、クローズし忘れに気を付けましょう。 第4引数はセキュリティ属性を格納したSECURITY_ATTRIBUTES構造体のアドレスを指定しますが、 既に存在するファイルに対しては無視されるので0を入れておきましょう。 第5引数はファイルをどうするか「動作」を以下の定数から指定します。
CREATE_NEW0x0001新規作成(同一ファイルが存在しない場合)
CREATE_ALWAYS0x0002新規作成(同一ファイルが存在すると上書)
OPEN_EXISTING0x0003開く(ファイルが存在する場合)
OPEN_ALWAYS0x0004開く(ファイルが存在しない場合は作成)
TRUNCATE_EXISTING0x0005サイズ0にして開く(ファイルが存在する場合)
今回は既に存在するファイルのタイムスタンプ変更なので、(=0x0003)が該当しますね。 第6引数は以下のファイル属性を指定します。
FILE_ATTRIBUTE_READONLY0x0001書き込みや削除が行えない読取専用ファイル。
FILE_ATTRIBUTE_HIDDEN0x0002通常のディレクトリリスティングでは表示されない隠しファイル。
FILE_ATTRIBUTE_SYSTEM0x0004OSのシステムファイル。
FILE_ATTRIBUTE_ARCHIVE0x0020バックアップや削除のためのマークとして使用するアーカイブファイル。
FILE_ATTRIBUTE_DEVICE0x0040予約済。
FILE_ATTRIBUTE_NORMAL0x0080属性を持たないファイル。他の属性を指定しない場合に適用される。
FILE_ATTRIBUTE_TEMPORARY0x0100必要がなくなった段階ですぐに削除すべき一時ファイル。
FILE_ATTRIBUTE_SPARSE_FILE0x0200未使用領域が多いか同じ値が長く続くスパースファイル。
FILE_ATTRIBUTE_REPARSE_POINT0x0400再解析ポイントが関連付けられているファイル。
FILE_ATTRIBUTE_COMPRESSED0x0800圧縮ファイル。
FILE_ATTRIBUTE_OFFLINE0x1000データがオフラインの記憶装置へ物理的に移動されたことを示すファイル。
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED0x2000「インデックスサービス」の対象ではないファイル。(Windows2000〜)
FILE_ATTRIBUTE_ENCRYPTED0x4000暗号化ファイル。
また、以下のオプションフラグを組み合わせることも可能です。
FILE_FLAG_OPEN_NO_RECALL0x00100000ローカルストレージに移されないようにする。
FILE_FLAG_OPEN_REPARSE_POINT0x00200000NTFSのリパースポイント機能の動作を禁止。
FILE_FLAG_POSIX_SEMANTICS0x01000000MS−DOS、16ビットアプリケーションからはアクセス不可。
FILE_FLAG_BACKUP_SEMANTICS0x02000000復元作業の為、呼出プロセスがセキュリティチェックをオーバーライド。
FILE_FLAG_DELETE_ON_CLOSE0x04000000全てのファイルハンドルがクローズするとファイルを削除。
FILE_FLAG_SEQUENTIAL_SCAN0x08000000シーケンシャルアクセス用に最適化されたファイルキャッシングを行う。
FILE_FLAG_RANDOM_ACCESS0x10000000ランダムアクセス用に最適化されたファイルキャッシングを行う。
FILE_FLAG_NO_BUFFERING0x20000000システムキャッシュを使用せずにファイルをオープン。
FILE_FLAG_OVERLAPPED0x40000000ファイルポインタを保持せずファイルに複数の操作を同時に行うことが可能。
FILE_FLAG_WRITE_THROUGH0x80000000キャッシュに書き込まれたデータをそのままディスクに書き込む。
第7引数はファイル属性と拡張属性を提供するテンプレートファイルへのハンドルを指定するとありますが、 ウィンドウズ9X系は指定できず、また、既存ファイルを開く場合は無視されるので0を指定します。 以上を指定してハンドルを受け取り、使用した後はAPI関数CloseHandleで解放します。 特に下記サンプルのように共有せず開いた場合、解放するまで他からファイルアクセスが出来なくなるので、 必ずクローズするようにしてください。 さて、API関数CreateFileで受け取ったハンドルをAPI関数GetFileTimeの第1引数に、 第2引数に作成日時を格納するFILETIME構造体のポインタ、 第3引数に最終アクセス日時を格納するFILETIME構造体のポインタ、 第4引数に最終書込日時を格納するFILETIME構造体のポインタをそれぞれ指定します。 FILETIME構造体は日付32ビット・時間32ビットの合計64ビットなので、 要素2以上の数値型配列変数の先頭アドレスを取得して設定します。 作成日時だけで良い…等、3つとも取得する必要がない場合は0を指定しておきましょう。 無事に日時が取得できると設定したFILETIME構造体に格納されるわけですが、 ファイルシステムがNTFSだと、入る時間が日本時間(JST)ではなく協定世界時(UTC)なので、 パソコンで設定されているタイムゾーンに変換するAPI関数FileTimeToLocalFileTimeを使います。 API関数FileTimeToLocalFileTimeについてはコチラを参照してください。 変換が終われば、冒頭で説明したシステム時刻に変換するAPI関数FileTimeToSystemTimeを使います。 API関数FileTimeToSystemTimeについてもコチラを参照してください。 取得とは逆のタイムスタンプの設定を行う方法についてはコチラを参照してください。

gettimestamp ファイルパス, タイプ
ファイルパスタイムスタンプ取得元のファイルパスを指定する。
refstrに「y/m/d h:m:s」形式でセットされる。
タイプ取得日時(0:作成 1:最終書込 2:最終アクセス)を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
	ll_libload kernel, "kernel32.dll"
	ll_getproc CreateFileA "CreateFileA", kernel
	ll_getproc CloseHandle "CloseHandle", kernel
	ll_getproc GetFileTime "GetFileTime", kernel
	ll_getproc FileTimeToLocalFileTime, "FileTimeToLocalFileTime", kernel
	ll_getproc FileTimeToSystemTime, "FileTimeToSystemTime", kernel

#module
#deffunc gettimestamp str, int
	mref file, 32 : mref type, 1
	mref rstr, 65
	prm = 0, 0, 0, 0, 0x0003, 0, 0
	ll_getptr file : ll_ret prm.0
	ll_callfunc prm, 7, CreateFileA@
	ll_ret hfile
	dim i, 4
	ll_getptr i : ll_ret j
	prm = hfile,(type = 0) * j, (type = 2) * j, (type = 1) * j
	ll_callfunc prm, 4, GetFileTime@
	prm = j, j
	ll_callfunc prm, 2, FileTimeToLocalFileTime@
	ll_callfunc prm, 2, FileTimeToSystemTime@
	ll_callfunc hfile, 1, CloseHandle@
	j = i.0 >>  0 & 0xFFFF : rstr  = ""  + j
	j = i.0 >> 16 & 0xFFFF : rstr += "/" + j
	j = i.1 >> 16 & 0xFFFF : rstr += "/" + j
	j = i.2 >>  0 & 0xFFFF : rstr += " " + j
	j = i.2 >> 16 & 0xFFFF : rstr += ":" + j
	j = i.3 >>  0 & 0xFFFF : rstr += ":" + j
	return
#global

	dialog "", 16, "タイムスタンプ取得対象ファイル"
	if stat = 0 : end
	path = refstr
	gettimestamp path, 0
	mes "作成日時    :" + refstr
	gettimestamp path, 1
	mes "最終書込日時  :" + refstr
	gettimestamp path, 2
	mes "最終アクセス日時:" + refstr
	stop

取得日時 = gettimestamp(ファイルパス, タイプ)
取得日時取得した「y/m/d h:m:s」形式の日時受取先を指定する。
ファイルパスタイムスタンプ取得元のファイルパスを指定する。
タイプ取得日時(0:作成 1:最終書込 2:最終アクセス)を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#uselib "kernel32.dll"
#cfunc	global CreateFileA "CreateFileA" sptr, int, int, int, int, int, int
#func	global CloseHandle "CloseHandle" int
#func	global GetFileTime "GetFileTime" int, int, int, int
#func	global FileTimeToLocalFileTime "FileTimeToLocalFileTime" var, var
#func	global FileTimeToSystemTime "FileTimeToSystemTime" var, var

#module
#defcfunc gettimestamp str file, int type, local i
	hfile = CreateFileA(file, , , , 0x0003)
	dim i, 4
	GetFileTime hfile, (type = 0) * varptr(i), (type = 2) * varptr(i), (type = 1) * varptr(i)
	FileTimeToLocalFileTime i, i
	FileTimeToSystemTime i, i
	CloseHandle hfile
	return "" + (i & 0xFFFF) + "/" + (i.0 >> 16) + "/" + (i.1 >> 16) + " " + (i.2 & 0xFFFF) + ":" + (i.2 >> 16) + ":" + (i.3 & 0xFFFF)
#global

	dialog "", 16, "タイムスタンプ取得対象ファイル"
	if stat = 0 : end
	path = refstr
	mes "作成日時    :" + gettimestamp(path, 0)
	mes "最終書込日時  :" + gettimestamp(path, 1)
	mes "最終アクセス日時:" + gettimestamp(path, 2)