大きいファイルの作成時刻を取得する時は要注意

ファイルが作られた時刻を取得したくてGoで調べてました。

やりたかったことは、あるディレクトリを監視して
ファイルが増えたら、新しいファイルのみ取得したいと思ってました。

じゃあこうしよう
「保存用最大ファイル作成時刻」とした変数を0としておく

  1. ディレクトリのファイルリストを取得する。
  2. その中の最大ファイル作成時刻を取得する。
  3. 2の時刻が「保存用最大ファイル作成時刻」より大きかったら、そのファイルが「新しいファイル」なので取得。
  4. 「保存用最大ファイル作成時刻」に2の時刻を更新する。

→繰り返し

っと考えた。
まあ監視するその時その時でファイル更新時刻がより大きければ新しいファイルでしょうと。

そこでGoでファイル作成時刻を取得しようとしたんだけど
ダイレクトにその変数がない。

ざっくりこんな感じ

import syscall
func main() {
  var s syscall.Stat_t
  syscall.Stat("/check_dir/file", &s)
  sec_a, _ := s.Atim.Unix()
  sec_m, _ := s.Mtim.Unix()
  sec_c, _ := s.Ctim.Unix()
}

Atim:最終アクセス日時
Mtim:最終更新日時
Ctim:属性変更日時

らしい。

ファイル作成日時というのはないらしい。

が!ここでファイルが100M程度のちょっと大きいファイルをコピーすると
コピー終わりきらないときに属性情報をみたら下記の通りだった。

それぞれ100M程度のtest01~03.gzをコピーしながら
属性情報を表示してる。

------------------
<コピー中>
test01.gz
Atim:1516762536
Mtim:1516755806
Ctim:1516779872

<コピー完了>
test01.gz
Atim:1516779876  //<---変わってる
Mtim:1516755806  //<---変わってる
Ctim:1516779872

------------------
<コピー中>
test02.gz
Atim:1516779876
Mtim:1516779876
Ctim:1516779876

<コピー完了>
test02.gz
Atim:1516779879  //<---変わってる
Mtim:1516755850  //<---変わってる
Ctim:1516779876

------------------
<コピー中>
test03.gz
Atim:1516762536
Mtim:1516755806
Ctim:1516779872

<コピー完了>
test03.gz
Atim:1516779876  //<---変わってる
Mtim:1516755806
Ctim:1516779872

最終アクセス日時と最終更新日時がコピー中とコピー完了時で変わってます。
当たり前だ!

属性変更日は変わらないようだけども、なんか怖いのでこれらの値を使わないほうがベターかも。

この方法はやめて単純にファイルリストから新しいファイルがあるかないかで判定しました。
このほうがいいね。

逆引きGolang (ファイル)
ascii.jp