我有一个脚本,需要根据文件的创建和修改日期做一些事情,但必须在Linux和Windows上运行。
在Python中获取文件创建和修改日期/时间的最佳跨平台方式是什么?
你有几个选择。其一,你可以使用 os.path.getmtime
和 os.path.getctime
函数。
import os.path, time
print("last modified: %s" % time.ctime(os.path.getmtime(file)))
print("created: %s" % time.ctime(os.path.getctime(file)))
你的另一个选择是使用os.stat
。
import os, time
(mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(file)
print("last modified: %s" % time.ctime(mtime))
注意。ctime()
并不是指*nix系统上的创建时间,而是指最后一次改变inode数据的时间。(感谢kojiro在评论中提供了一个有趣的博文链接,使这个事实更加清晰)
以跨平台的方式获取某种修改日期是很容易的--只要调用[os.path.getmtime(path)
][1],你'就会得到path
处的文件最后一次修改的Unix时间戳。
另一方面,获取文件的*创建日期是很麻烦的,而且依赖于平台,甚至在三大操作系统之间也有所不同。
ctime
(在 https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx 上有记载)存储了它的创建日期。
在Python中,你可以通过os.path.getctime()
或调用[os.stat()
][4]结果的[.st_ctime
][2]属性来访问它。
这在 Unix 上是行不通的,因为在 Unix 上,ctime
是文件的属性或内容最后一次被更改的时间。os.stat()
的结果的.st_birthtime
属性。ext4
将它们存储在st_crtime
中),但Linux内核没有提供访问它们的方法。
特别是,它从C语言中的stat()
调用中返回的结构,在最新的内核版本中,不包含任何创建日期字段。
你也可以看到,标识符st_crtime
目前在Python源码中的任何地方都没有特色。
至少如果你在ext4
上,数据*是附着在文件系统中的inodes上的,但是没有方便的方式来访问它。在Linux上,下一个最好的办法是通过os.path.getmtime()
或os.stat()
结果的[.st_mtime
][3]属性来访问文件的mtime
。
这将给出文件内容最后一次被修改的时间,这对于某些用例来说可能已经足够了。
把这些放在一起,跨平台的代码应该是这样的......。
import os
import platform
def creation_date(path_to_file):
"""
Try to get the date that a file was created, falling back to when it was
last modified if that isn't possible.
See http://stackoverflow.com/a/39501288/1709587 for explanation.
"""
if platform.system() == 'Windows':
return os.path.getctime(path_to_file)
else:
stat = os.stat(path_to_file)
try:
return stat.st_birthtime
except AttributeError:
# We're probably on Linux. No easy way to get creation dates here,
# so we'll settle for when its content was last modified.
return stat.st_mtime
[1]: https://docs.python.org/library/os.path.html#os.path.getmtime [2]: https://docs.python.org/3/library/os.html#os.stat_result.st_ctime [3]: https://docs.python.org/3/library/os.html#os.stat_result.st_mtime [4]: https://docs.python.org/3/library/os.html#os.stat
最好的函数是 [os.path.getmtime()][1]。
在内部,这只是使用os.stat(filename).st_mtime
。
datetime模块是最擅长处理时间戳的模块,所以你可以像这样以datetime
对象的形式获取修改日期。
import os
import datetime
def modification_date(filename):
t = os.path.getmtime(filename)
return datetime.datetime.fromtimestamp(t)
使用实例。
>>> d = modification_date('/var/log/syslog')
>>> print d
2009-10-06 10:50:01
>>> print repr(d)
datetime.datetime(2009, 10, 6, 10, 50, 1)
[1]: http://docs.python.org/library/os.path.html#os.path.getmtime
os.stat https://docs.python.org/2/library/stat.html#module-stat
编辑:在较新的代码中,你可能应该使用 os.path.getmtime() (感谢 Christian Oudard) 但请注意,它返回的是一个带有分数秒的浮点值time_t(如果你的操作系统支持它的话)
有两种方法可以获得mod时间,os.path.getmtime()或os.stat(),但ctime在跨平台上不可靠(见下文)。
getmtime(path)
*返回路径的最后修改时间。返回值是一个数字,表示
返回值是一个数字,表示自纪元以来的秒数(见时间模块)。如果文件不存在或无法访问,则引发os.error
不存在或无法访问,则引发os.error。在1.5.2版本中新增。在2.3版本中改变了:如果
os.stat_float_times() 返回 True,结果是一个浮点数字。
stat(path)
在给定的路径上执行 stat() 系统调用。返回值是一个对象,其
其属性与stat结构的成员相对应,即:st_mode(保护
位),st_ino(节点号),st_dev(设备),st_nlink(硬链接的数量),st_uid
(所有者的用户ID), st_gid (所有者的组ID), st_size (文件的大小,字节数)。
st_atime (最近一次访问的时间), st_mtime (最近一次修改内容的时间)
修改的时间),st_ctime(取决于平台;在Unix上是最近的元数据变化时间,在Windows上是创建时间)。
>>> import os
>>> statinfo = os.stat('somefile.txt')
>>> statinfo
(33188, 422511L, 769L, 1, 1032, 100, 926L, 1105022698,1105022732, 1105022732)
>>> statinfo.st_size
926L
>>>
在上面的例子中,你可以使用statinfo.st_mtime或statinfo.st_ctime来分别获得mtime和ctime。
在Python 3.4及以上版本中,你可以使用面向对象的pathlib模块接口,它包含了许多os模块的封装器。 下面是一个获取文件统计的例子。
>>> import pathlib
>>> fname = pathlib.Path('test.py')
>>> assert fname.exists(), f'No such file: {fname}' # check that the file exists
>>> print(fname.stat())
os.stat_result(st_mode=33206, st_ino=5066549581564298, st_dev=573948050, st_nlink=1, st_uid=0, st_gid=0, st_size=413, st_atime=1523480272, st_mtime=1539787740, st_ctime=1523480272)
关于os.stat_result
所包含内容的更多信息,请参考文档。
对于修改时间,你需要fname.stat().st_mtime
。
>>> import datetime
>>> mtime = datetime.datetime.fromtimestamp(fname.stat().st_mtime)
>>> print(mtime)
datetime.datetime(2018, 10, 17, 10, 49, 0, 249980)
如果你想知道Windows上的创建时间,或者Unix上最近的元数据变化,你可以使用fname.stat().st_ctime
。
>>> ctime = datetime.datetime.fromtimestamp(fname.stat().st_ctime)
>>> print(ctime)
datetime.datetime(2018, 4, 11, 16, 57, 52, 151953)
本文有更多关于pathlib模块的有用信息和例子。
import os, time, datetime
file = "somefile.txt"
print(file)
print("Modified")
print(os.stat(file)[-2])
print(os.stat(file).st_mtime)
print(os.path.getmtime(file))
print()
print("Created")
print(os.stat(file)[-1])
print(os.stat(file).st_ctime)
print(os.path.getctime(file))
print()
modified = os.path.getmtime(file)
print("Date modified: "+time.ctime(modified))
print("Date modified:",datetime.datetime.fromtimestamp(modified))
year,month,day,hour,minute,second=time.localtime(modified)[:-3]
print("Date modified: %02d/%02d/%d %02d:%02d:%02d"%(day,month,year,hour,minute,second))
print()
created = os.path.getctime(file)
print("Date created: "+time.ctime(created))
print("Date created:",datetime.datetime.fromtimestamp(created))
year,month,day,hour,minute,second=time.localtime(created)[:-3]
print("Date created: %02d/%02d/%d %02d:%02d:%02d"%(day,month,year,hour,minute,second))
印花
somefile.txt
Modified
1429613446
1429613446.0
1429613446.0
Created
1517491049
1517491049.28306
1517491049.28306
Date modified: Tue Apr 21 11:50:46 2015
Date modified: 2015-04-21 11:50:46
Date modified: 21/04/2015 11:50:46
Date created: Thu Feb 1 13:17:29 2018
Date created: 2018-02-01 13:17:29.283060
Date created: 01/02/2018 13:17:29
如果跟踪符号链接不重要,也可以使用内置的os.lstat
。
>>> os.lstat("2048.py")
posix.stat_result(st_mode=33188, st_ino=4172202, st_dev=16777218L, st_nlink=1, st_uid=501, st_gid=20, st_size=2078, st_atime=1423378041, st_mtime=1423377552, st_ctime=1423377553)
>>> os.lstat("2048.py").st_atime
1423378041.0
我能够通过运行系统的统计命令并解析输出结果来获得posix的创建时间。
commands.getoutput('stat FILENAME').split('\"')[7]
在终端机(OS X)上运行python之外的统计信息,返回:
805306374 3382786932 -rwx------ 1 km staff 0 1098083 "Aug 29 12:02:05 2013" "Aug 29 12:02:05 2013" "Aug 29 12:02:20 2013" "Aug 27 12:35:28 2013" 61440 2150 0 testfile.txt
。
805306374 3382786932 -rwx------ 1 km staff 0 1098083 "Aug 29 12:02:05 2013" "Aug 29 12:02:05 2013" "Aug 29 12:02:20 2013" "Aug 27 12:35:28 2013" 61440 2150 0 testfile.txt
... 其中第四个日期时间是文件创建时间(而不是其他评论中提到的ctime改变时间)。