はじめに
ファイルの一覧を標準出力するときに、ファイルの変更日時を見てfilterしたいときがあって調べました。
ファイルに関する日時
stat
コマンドでファイルを確認すると、以下の3つの日時を保持しています。Birthという項目もあるのですが-
になっています。カーネルがxstat()
を提供しているかに依存するそうです。なので、私の環境では見れないみたいです。
- Access: 2018-07-16 14:39:26.824920847 +0900
- Modify: 2018-07-17 09:47:15.038632561 +0900
- Change: 2018-07-18 21:07:34.324530860 +0900
Access
Accessは最後に利用した日時です。
以下で更新されます。
- エディタで開く
Modify
Modifyは最後に修正した日時です。
以下で更新されます。
- エディタで書き込み
- リダイレクトによる書き込み
Change
Changeは最後に変更した日時です。
以下で更新されます。
- エディタで書き込み
- リダイレクトによる書き込み
- ファイル名の変更(ファイルの移動)
Goでファイルの日時を取得する
ファイルの情報はtype FileInfo interface
で、下記の値を取得できます。
メソッド名 | 概要 |
---|---|
Name() | ファイル名 |
Size() | ファイルサイズ |
Mode() | 読み込み、書き込み、実行 |
ModTime() | 修正日時 |
IsDir() | ディレクトリかどうか |
Sys() | 基礎情報 |
見て分かるとおり、Modifyしか取得できません。
AccessとChangeを取得するには、Sys()から取らなければなりません。
まず、Sys()がinterfaceなのでsyscall.Stat_t
にキャストします。
そして、LinuxならAtime,CtimeというTimespec構造体から値を取り出します。
MacOSならAtimespec,Ctimespecらしいです。手元にMacOSがないため検証はしていません。
Nano()でナノ秒で値が返ってきます。
if internalStat, ok := fileInfo.Sys().(*syscall.Stat_t); ok {
fmt.Printf("Access: %v\n", internalStat.Atim.Nano())
fmt.Printf("Change: %v\n", internalStat.Ctim.Nano())
}