Mac上修改/创建/访问时间不一致

8 投票
1 回答
2421 浏览
提问于 2025-04-15 20:36

我在使用 os.utime 来设置 Mac 上的修改时间时遇到了麻烦(我用的是 Mac OS X 10.6.2,运行的是 /usr/bin/python 下的 Python 2.6.1)。它的表现和 touch 工具不一致,而且在 Finder 的“获取信息”窗口中显示的属性也不一致。

考虑一下以下的命令序列。这里提到的“创建时间”和“修改时间”是指在 Finder 的“获取信息”窗口中显示的属性。提醒一下,os.utime 接受的参数是 (filename, (atime, mtime))

>>> import os
>>> open('tempfile','w').close()

“创建时间”和“修改时间”都是当前时间。

>>> os.utime('tempfile', (1000000000, 1500000000) )

“创建时间”是当前时间,“修改时间”是 2017 年 7 月 13 日。

>>> os.utime('tempfile', (1000000000, 1000000000) )

“创建时间”和“修改时间”都是 2001 年 9 月 8 日。

>>> os.path.getmtime('tempfile')
1000000000.0
>>> os.path.getctime('tempfile')
1269021939.0
>>> os.path.getatime('tempfile')
1269021951.0

...但是 os.path.get?timeos.stat 并没有反映这些变化。

>>> os.utime('tempfile', (1500000000, 1000000000) )

“创建时间”和“修改时间”仍然都是 2001 年 9 月 8 日。

>>> os.utime('tempfile', (1500000000, 1500000000) )

“创建时间”是 2001 年 9 月 8 日,“修改时间”是 2017 年 7 月 13 日。

我不确定这是 Python 的问题还是 Mac 的 stat 问题。当我退出 Python 终端并运行

touch -a -t 200011221234 tempfile

时,修改时间和创建时间都没有变化,正如预期的那样。然后我运行

touch -m -t 200011221234 tempfile

,这时“创建时间”和“修改时间”都发生了变化。

有没有人知道这是怎么回事?我该如何在 Mac 上一致地更改修改时间和创建时间?(是的,我知道在类 Unix 系统中没有“创建时间”。)


运行 Chris Johnsen 的脚本后的结果:

seth@local:~$ /usr/bin/python timetest.py tempfile 5
initial:
(1269631281.0, 1269631281.0, 1269631281.0, 1269631281, 1269631281, 1269631281)

test: (1000000000, 1000000000)
(1000000000.0, 1000000000.0, 1269631281.0, 1000000000, 1000000000, 1269631281)
(1269631281.0, 1000000000.0, 1269631281.0, 1269631281, 1000000000, 1269631281)

test: (1000000000, 1500000000)
(1000000000.0, 1500000000.0, 1269631286.0, 1000000000, 1500000000, 1269631286)
(1269631286.0, 1500000000.0, 1269631286.0, 1269631286, 1500000000, 1269631286)

test: (1500000000, 1000000000)
(1500000000.0, 1000000000.0, 1269631291.0, 1500000000, 1000000000, 1269631291)
(1269631291.0, 1000000000.0, 1269631291.0, 1269631291, 1000000000, 1269631291)

test: (1500000000, 1500000000)
(1500000000.0, 1500000000.0, 1269631296.0, 1500000000, 1500000000, 1269631296)
(1269631296.0, 1500000000.0, 1269631296.0, 1269631296, 1500000000, 1269631296)

在这个操作结束时,Finder 中可见的“创建时间”是 2001 年 9 月 8 日,“修改时间”是 2017 年 7 月 13 日。(访问时间,可能是因为 Spotlight 的原因,正如你所提到的,我也读过相关内容,大致是“现在”。)在 Finder 中可见的创建和修改日期仍然没有意义。

1 个回答

5

POSIX atimemtimectime

如果你能提供一个完整的脚本以及它的实际输出和预期输出,而不是只给出一些代码片段,那可能会更有帮助。

import sys, os, stat, time

def get_times(p):
    s = os.stat(p)
    return ( 
        os.path.getatime(p),
        os.path.getmtime(p),
        os.path.getctime(p),
        s[stat.ST_ATIME],
        s[stat.ST_MTIME],
        s[stat.ST_CTIME],
    )

def main(p, delay=1):
    delay = float(delay)
    (a,b) = (1000000000, 1500000000)

    open(p,'w').close()

    print 'initial:'
    print get_times(p)

    for t in [ (a,a), (a,b), (b,a), (b,b) ]:
        print
        print 'test:', t
        os.utime(p,t)
        print get_times(p)
        time.sleep(delay)
        print get_times(p)

main(*sys.argv[1:])

在我的10.4系统上,我用命令cd "$HOME" && python test.py tempfile 5运行这个(系统默认的Python 2.3.6和MacPorts的Python 2.6.4都给出了相同的结果,当然不包括最初的时间和ctime):

% python /tmp/test.py tempfile 5
initial:
(1000000000.0, 1000000000.0, 1269629881.0, 1000000000, 1000000000, 1269629881)

test: (1000000000, 1000000000)
(1000000000.0, 1000000000.0, 1269629881.0, 1000000000, 1000000000, 1269629881)
(1000000000.0, 1000000000.0, 1269629881.0, 1000000000, 1000000000, 1269629881)

test: (1000000000, 1500000000)
(1000000000.0, 1500000000.0, 1269629886.0, 1000000000, 1500000000, 1269629886)
(1000000000.0, 1500000000.0, 1269629886.0, 1000000000, 1500000000, 1269629886)

test: (1500000000, 1000000000)
(1500000000.0, 1000000000.0, 1269629891.0, 1500000000, 1000000000, 1269629891)
(1500000000.0, 1000000000.0, 1269629891.0, 1500000000, 1000000000, 1269629891)

test: (1500000000, 1500000000)
(1500000000.0, 1500000000.0, 1269629896.0, 1500000000, 1500000000, 1269629896)
(1500000000.0, 1500000000.0, 1269629896.0, 1500000000, 1500000000, 1269629896)

这看起来合理。我想知道你得到的结果是什么。

我听说Spotlight有时会因为重新索引更改过的文件而强行重置atime。我不认为它会重新索引只经过utime()/utimes()处理的文件,但我想这也是有可能的。为了避免Spotlight带来的麻烦,可以使用一个不在Spotlight索引中的文件(例如/tmp/testfile)。

Finder中创建的日期

(在Finder的“获取信息”窗口中显示为“创建时间:”)

如果你安装了开发者工具,可以使用/Developer/Tools/GetFileInfo来查看HFS的创建日期。我在每个print get_times(p)行后添加了以下几行:

sys.stdout.flush()
os.system('/Developer/Tools/GetFileInfo ' + p)

我还把循环改成了与你最初描述的一致([ (a,b), (a,a), (b,a), (b,b) ])。

现在的结果看起来是这样的:

% rm /tmp/tempfile; python /tmp/test.py /tmp/tempfile 1
initial:
(1269636574.0, 1269636574.0, 1269636574.0, 1269636574, 1269636574, 1269636574)
file: "/private/tmp/tempfile"
type: ""
creator: ""
attributes: avbstclinmedz
created: 03/26/2010 15:49:34
modified: 03/26/2010 15:49:34

test: (1000000000, 1500000000)
(1000000000.0, 1500000000.0, 1269636574.0, 1000000000, 1500000000, 1269636574)
file: "/private/tmp/tempfile"
type: ""
creator: ""
attributes: avbstclinmedz
created: 03/26/2010 15:49:34
modified: 07/13/2017 21:40:00
(1000000000.0, 1500000000.0, 1269636574.0, 1000000000, 1500000000, 1269636574)
file: "/private/tmp/tempfile"
type: ""
creator: ""
attributes: avbstclinmedz
created: 03/26/2010 15:49:34
modified: 07/13/2017 21:40:00

test: (1000000000, 1000000000)
(1000000000.0, 1000000000.0, 1269636576.0, 1000000000, 1000000000, 1269636576)
file: "/private/tmp/tempfile"
type: ""
creator: ""
attributes: avbstclinmedz
created: 09/08/2001 20:46:40
modified: 09/08/2001 20:46:40
(1000000000.0, 1000000000.0, 1269636576.0, 1000000000, 1000000000, 1269636576)
file: "/private/tmp/tempfile"
type: ""
creator: ""
attributes: avbstclinmedz
created: 09/08/2001 20:46:40
modified: 09/08/2001 20:46:40

test: (1500000000, 1000000000)
(1500000000.0, 1000000000.0, 1269636577.0, 1500000000, 1000000000, 1269636577)
file: "/private/tmp/tempfile"
type: ""
creator: ""
attributes: avbstclinmedz
created: 09/08/2001 20:46:40
modified: 09/08/2001 20:46:40
(1500000000.0, 1000000000.0, 1269636577.0, 1500000000, 1000000000, 1269636577)
file: "/private/tmp/tempfile"
type: ""
creator: ""
attributes: avbstclinmedz
created: 09/08/2001 20:46:40
modified: 09/08/2001 20:46:40

test: (1500000000, 1500000000)
(1500000000.0, 1500000000.0, 1269636578.0, 1500000000, 1500000000, 1269636578)
file: "/private/tmp/tempfile"
type: ""
creator: ""
attributes: avbstclinmedz
created: 09/08/2001 20:46:40
modified: 07/13/2017 21:40:00
(1500000000.0, 1500000000.0, 1269636578.0, 1500000000, 1500000000, 1269636578)
file: "/private/tmp/tempfile"
type: ""
creator: ""
attributes: avbstclinmedz
created: 09/08/2001 20:46:40
modified: 07/13/2017 21:40:00

这似乎和你在Finder的“获取信息”窗口中的观察结果一致。我的理解(通过其他实验得出的)是,HFS的创建日期会被utime更新,但它只会向后更新(不会向前)。如果你想把HFS的创建日期更新为一个新的值,可能需要使用特定于Mac的API来实现。

还有一点需要注意:你可能需要切换一下窗口,才能让获取信息窗口更新。在我的系统上,除非我切换到或离开获取信息窗口,否则它的显示不会自动更新。

撰写回答