访问 ctime 不会返回文件的创建时间。

huangapple go评论100阅读模式
英文:

accessing ctime does not return the creation time of a file

问题

我有一个包含以下信息的文件(mac os):

创建时间:2020年5月26日星期二,11:21
修改时间:2021年5月26日,15:40

经过一些研究后,我尝试了以下操作:

ctim := fi.Sys().(*syscall.Stat_t).Ctim

atim := fi.Sys().(*syscall.Stat_t).Atim
mtim := fi.Sys().(*syscall.Stat_t).Mtim
log.Println("ctim:", time.Unix(ctim.Sec, ctim.Nsec))
log.Println("atim:", time.Unix(atim.Sec, atim.Nsec))
log.Println("mtim:", time.Unix(mtim.Sec, mtim.Nsec))

但它们都返回:

app_1  | 2021/05/26 15:40:17 ctim: 2021-05-26 15:40:17.199113879 +0000 UTC
app_1  | 2021/05/26 15:40:17 atim: 2021-05-26 15:40:16.457499729 +0000 UTC
app_1  | 2021/05/26 15:40:17 mtim: 2021-05-26 15:40:05.982391804 +0000 UTC

而且我正在使用docker + docker-compose,从golang:1.14-stretch构建,并在debian:bullseye-slim中保存二进制文件。

显然,这不是文件的创建时间。有没有办法可以获取这些信息?

英文:

I have a file with this from the info (mac os):

Created: Tuesday, 26 May 2020 at 11:21
Modified: 26 May 2021 at 15:40

And after some research I tried to do:

ctim := fi.Sys().(*syscall.Stat_t).Ctim

atim := fi.Sys().(*syscall.Stat_t).Atim
mtim := fi.Sys().(*syscall.Stat_t).Mtim
log.Println("ctim:", time.Unix(ctim.Sec, ctim.Nsec))
log.Println("atim:", time.Unix(atim.Sec, atim.Nsec))
log.Println("mtim:", time.Unix(mtim.Sec, mtim.Nsec))

but they all return:

app_1  | 2021/05/26 15:40:17 ctim: 2021-05-26 15:40:17.199113879 +0000 UTC
app_1  | 2021/05/26 15:40:17 atim: 2021-05-26 15:40:16.457499729 +0000 UTC
app_1  | 2021/05/26 15:40:17 mtim: 2021-05-26 15:40:05.982391804 +0000 UTC

Also I'm using docker + docker-compose, building from golang:1.14-stretch and saving binary within debian:bullseye-slim.

Clearly this is not the creation time of the file. Any idea how I can get this information?

答案1

得分: 7

ctime不是“创建时间”,而是“inode更改时间”。

OSX有“创建时间”,Finder显示为“创建日期”,在OSX上的Go(GOOS=darwin)中,它作为syscall.Stat_tBirthtimespec字段可用。

然而,创建时间并没有被POSIX定义,许多其他Unix系统要么没有这个概念,要么不将其暴露给用户程序。Linux就是其中之一,直到最近为止,它的stat系统调用不返回birthtime,因此Go的os.Stat也不返回。Linux 4.11中添加了statx系统调用,确实返回它,但这不在Go标准库中。

golang.org/x/sys/unix支持statx,但它是一个相当底层的接口(例如,它需要一个打开目录的整数文件描述符号;它不能直接在os.File上工作)。如果它在一个版本过旧的Linux上运行,它还可能返回ENOSYS错误,即使它足够新,你得到的Btime也可能为零,如果你调用它的文件位于不支持birth time的文件系统上,或者如果该文件系统的Linux文件系统驱动程序简单地还没有更新。

英文:

ctime isn't "creation time", it's "inode change time".

OSX has "birth time", which is what the Finder displays as "creation date", and in Go on OSX (GOOS=darwin) it's available as the Birthtimespec field of syscall.Stat_t.

However, birth time isn't defined by POSIX, and many other Unix systems either don't have the concept, or don't expose it to user programs. Linux was one of those until quite recently; its stat syscall doesn't return birthtime, and so Go's os.Stat doesn't either. The statx syscall, added in Linux 4.11, does return it, but that's not in the Go stdlib.

statx is supported by golang.org/x/sys/unix but it's a rather low-level interface (for instance it requires an integer file descriptor number of an open directory; it doesn't work directly on an os.File). It also might return an ENOSYS error if it's running on a version of Linux that's too old, and even if it's new enough, the Btime you get back might be zero if the file you call it on is on a filesystem without birth time support, or if the Linux filesystem driver for that filesystem simply hasn't been updated.

huangapple
  • 本文由 发表于 2021年5月26日 23:52:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/67708474.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定