在Mac上使用Python获取文件创建时间

12 投票
3 回答
8532 浏览
提问于 2025-04-15 12:01

在Mac上,Python的os.path.getctime这个功能其实并不是用来获取文件创建的时间,而是用来获取“最后一次修改的时间”(根据文档的说法)。不过在Finder里,我可以看到文件的真实创建时间,这些信息是由HFS+文件系统保存的。

你有没有什么建议,能让我在Python程序中获取Mac上文件的创建时间呢?

3 个回答

3

由于没有找到合适的工具,我自己创建了一个叫做 crtime 的程序。

pip install crtime

然后你可以这样使用它:

sudo crtime ./

这将输出:

1552938281  /home/pascal/crtime/.gitignore
1552938281  /home/pascal/crtime/README.md
1552938281  /home/pascal/crtime/crtime
1552938281  /home/pascal/crtime/deploy.py
1552938281  /home/pascal/crtime/setup.cfg
1552938281  /home/pascal/crtime/setup.py
1552938961  /home/pascal/crtime/crtime.egg-info
1552939447  /home/pascal/crtime/.git
1552939540  /home/pascal/crtime/build
1552939540  /home/pascal/crtime/dist

需要注意的是,对于大文件夹来说,它的速度会比有时提到的 xstat 快1000倍,因为它会先创建一个临时文件,然后一次性对所有文件执行 stat 操作。

3

ctime在不同平台上是有区别的:在一些系统(比如Unix)上,它表示最后一次元数据更改的时间,而在其他系统(比如Windows)上,它表示创建时间。这是因为Unix系统通常不保留“原始”的创建时间。

不过,你可以通过使用stat模块来获取操作系统提供的所有信息。

stat模块定义了一些常量和函数,用于解释os.stat()、os.fstat()和os.lstat()的结果(如果它们存在的话)。要了解stat、fstat和lstat的详细信息,请查阅你系统的相关文档。

stat.ST_CTIME
操作系统报告的“ctime”。在一些系统(比如Unix)上,它是最后一次元数据更改的时间,而在其他系统(比如Windows)上,它是创建时间(具体细节请查看平台文档)。

25

使用st_birthtime这个属性,可以从调用os.stat()(或者是fstat/lstat)的结果中获取文件的创建时间。

def get_creation_time(path):
    return os.stat(path).st_birthtime

你可以通过datetime.datetime.fromtimestamp()把得到的整数结果转换成日期时间对象。

我记得在这个回答最初写的时候,这个方法在Mac OS X上可能不太好用,但我可能记错了,现在即使是旧版本的Python也能正常工作。下面是旧的回答,留作参考。


使用ctypes来访问系统调用stat64(适用于Python 2.5及以上版本):

from ctypes import *

class struct_timespec(Structure):
    _fields_ = [('tv_sec', c_long), ('tv_nsec', c_long)]

class struct_stat64(Structure):
    _fields_ = [
        ('st_dev', c_int32),
        ('st_mode', c_uint16),
        ('st_nlink', c_uint16),
        ('st_ino', c_uint64),
        ('st_uid', c_uint32),
        ('st_gid', c_uint32), 
        ('st_rdev', c_int32),
        ('st_atimespec', struct_timespec),
        ('st_mtimespec', struct_timespec),
        ('st_ctimespec', struct_timespec),
        ('st_birthtimespec', struct_timespec),
        ('dont_care', c_uint64 * 8)
    ]

libc = CDLL('libc.dylib') # or /usr/lib/libc.dylib
stat64 = libc.stat64
stat64.argtypes = [c_char_p, POINTER(struct_stat64)]

def get_creation_time(path):
    buf = struct_stat64()
    rv = stat64(path, pointer(buf))
    if rv != 0:
        raise OSError("Couldn't stat file %r" % path)
    return buf.st_birthtimespec.tv_sec

使用subprocess来调用stat工具:

import subprocess

def get_creation_time(path):
    p = subprocess.Popen(['stat', '-f%B', path],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    if p.wait():
        raise OSError(p.stderr.read().rstrip())
    else:
        return int(p.stdout.read())

撰写回答