英文:
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_t的Birthtimespec
字段可用。
然而,创建时间并没有被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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论