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

时间:2010-03-19 18:28:15

标签: python macos touch stat

我无法使用os.utime在Mac上正确设置修改时间(Mac OS X 10.6.2,从/usr/bin/python运行Python 2.6.1)。它与touch实用程序不一致,并且与Finder的“获取信息”窗口中显示的属性不一致。

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

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

'created'和'modified'都是当前时间。

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

'created'是当前时间,'modified'是2017年7月13日。

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

'created'和'modified'都是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日,

'created'和'modified'仍然是

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

'created'是2001年9月8日,'modified'是2017年7月13日。

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

touch -a -t 200011221234 tempfile

修改和创建时间都没有像预期的那样改变。然后我跑

touch -m -t 200011221234 tempfile

并且“已创建”和“已修改”时间都已更改。

有谁知道发生了什么事?如何在mac上一致地更改修改和创建时间? (是的,我知道在Unixy系统上没有“创建时间”。)


运行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)

在练习结束时,查找器中显示的“创建”日期是9/8/01,“修改”日期是7/13/17。 (访问日期,正如你所建议的那样,正如我所读到的那样,大概是'现在'。)在查找器中可见的创建和修改日期仍然没有意义。

2 个答案:

答案 0 :(得分:2)

POSIX atime mtime ctime

如果您包含完整脚本及其实际和预期输出而不是REPL片段,则可能会有所帮助。

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工具,则可以使用/Developer/Tools/GetFileInfo查看HFS creationDate。我在每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 creationDate更新为更新的值,那么您可能必须使用特定于Mac的API来执行此操作。

另一个注意事项:您可能需要稍微切换窗口才能更新获取信息窗口。在我的系统上,除非我将窗口切换到Get Info窗口或从Get Info窗口切换窗口,否则它的显示不会自动更新。

答案 1 :(得分:0)

Mac OS维护不会映射到posix的额外属性。

  • createDate
  • contentModDate
  • attributeModDate
  • accessDate
  • backupDate

您曾经能够通过旧的macfs模块访问这些模块,这个模块很久以前就被弃用了,而Carbon模块在很大程度上没有文档化,现在也被弃用了。我认为Carbon.File和Carbon.Folder有你需要的东西。 (我没有足够地关注Mac以了解当前这些功能的计划。也许Carbon正在从stdlib中撤出,并且它将自行继续。)

也许评论详细说明您正在寻找的内容会有所帮助,而不是downvote

我不确定您期望的其他一致性。 Python正在使用posix api,Apple工具正在使用Apple的api。每一个似乎都是内部一致的,但它们之间可能有所不同。

  • attributeModDate映射到ctime。
  • createDate是Finder为“created”
  • 显示的内容
  • 如果您将mtime更改为早于createDate,则mac文件系统api将更改createDate以匹配;这可以防止在创建之前出现明显修改的不一致。这解决了我可以从上面的示例中收集的唯一不一致的行为。