ctime总是<= mtime?

在Python中使用os.stat()时,我可以假设st_ctime总是小于或等于st_mtime吗? 如果没有,为什么不呢?

该代码将始终在Linux上运行,但是如果在操作系统之间存在差异,那么很好理解。

在某些情况下,这个假设可能被证明是无效的(并且很大程度上取决于操作系统的实现):

  • 时区。 如果您在UTC + 4中创建文件,然后在当前时区为UTC-8时对其进行修改,并且操作系统不对后台中的所有时间戳使用UTC,则修改的时间将少于比创建的时间。 在这种情况下,现代操作系统(Windows,OSX,BSD或Linux之一)具有mtime <ctime是令人惊讶的。
  • 重置操作系统时间。 这可能会影响修改时间来创建这种情况。 我想说,假设在文件系统驱动程序中没有检查来避免这种情况,那么在这种情况下,你将有更多的时间没有操作系统的投诉。
  • 通过系统调用修改时间。 同样,文件系统驱动程序可能会进行检查以避免这种异常情况。

这两者都是可重复的:您最好的选择是采用您计划定位和测试此行为的各种操作系统。 我所能提供的只是猜测。

此外 ,st_ctime不一定是“创建时间”,而是“最后状态更改”( 源 )的时间。 utime标记要更新的文件的ctime ( 源 ),它的类型为“utimbuf”的参数没有用于ctime成员。 因此,如果操作系统和文件系统允许的话,ctime在技术上是可能的。 os.stat文档实际上提到了这一点:

平台依赖; Unix上最新的元数据更改时间,或Windows上的创建时间

虽然Python隐藏了许多事物的C端, os.stat和friends都是建立在相同的基本C系统调用之上的,所以它们的规范是寻找更多信息的好地方。

请定义“小于”,你的意思是更新还是更旧? 您不能假定ctime在mtime之前发生,但通常ctime与mtime是相同的或之后的。

Unix上的ctime不是“创建时间”,而是“更改时间”。 当一个文件的内容被改变时,mtime被更新,但是当文件元数据被改变时(这意味着当mtime被更新时它被更新),ctime被更新,所以ctime在mtime之后是完全正常的。 这是一个例子:

 user@ubuntu:~$ touch test user@ubuntu:~$ chmod 600 test user@ubuntu:~$ stat test File: «test» Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 700h/1792d Inode: 222375 Links: 1 Access: (0600/-rw-------) Uid: ( 1000/ user) Gid: ( 1000/ user) Access: 2011-01-03 12:35:15.945973569 +0100 Modify: 2011-01-03 12:35:15.945973569 +0100 Change: 2011-01-03 12:35:24.024998291 +0100 

另外,我相信在Windows上,ctime字段确实意味着“创建时间”,这是Windows和Unix之间的差异。 我已经在网上阅读了一些关于这方面的内容,但是我会让你做一下你自己的研究。

以编程方式设置两个值是完全可能的。 通过将时钟设置回文件创建之前,您也可以“自然地”发生这种情况。

换句话说,是的。 这将是不寻常的,但完全有可能。

你有这个错误的方式! 在Linux(或Mac,或任何其他Unix系统)上, ctime通常总是比mtime更早,而不是更早。 与Windows不同的是, ctime是文件创建日期, mtime是文件修改日期,在Unix中它们都是修改日期,不同之处在于:

  • 只要文件内容发生变化, mtime就会被更新
  • 每当文件属性更改时(包括其mtimectime都会更新

stat实用程序 (至少是某些变体)的手册页分别称为“上次数据修改 时间 “上次状态更改时间”

因此,无论何时更新mtimectime也会得到更新。 我所知道的唯一可以获得大于ctimemtime机制是:

  • 使用utimeutimes系统调用手动将mtime设置为未来,或使用它们的实用程序,如touch -d
  • 以绕过Linux文件系统API的方式写入磁盘,或者完全绕过文件系统,如:
    • 从Windows写入磁盘
    • 打开磁盘的设备文件并写入
    • 用激光,磁铁, 超声波螺丝刀或类似物在磁盘上翻转位

既然你已经在Python的环境中问过了,那么让我们来做一个简单的Python工具,输出给定文件的mtimectime来帮助我们演示这个。 我们将在脚本中使用方便的os.path.getctimeos.path.getctime API,但是使用stat调用结果的st_ctimest_mtime属性可以得到完全相同的结果:

 #!/usr/bin/python import os import sys target_filename = sys.argv[1] mtime = os.path.getmtime(target_filename) ctime = os.path.getctime(target_filename) print('mtime: %f ctime: %f' % (mtime, ctime)) 

我们可以将其保存为pystat.py ,使其可执行,并在我们的Unix shell中进行实验:

 $ # Times are initially equal: $ touch foo $ ./pystat.py foo mtime: 1473979539.786961 ctime: 1473979539.786961 $ $ # It doesn't matter how I create the file: $ echo qwerty > bar $ ./pystat.py bar mtime: 1473979561.218961 ctime: 1473979561.218961 $ $ # 'touch'ing a created file updates both times: $ touch foo $ ./pystat.py foo mtime: 1473979584.642960 ctime: 1473979584.642960 $ $ touch bar $ ./pystat.py bar mtime: 1473979592.762960 ctime: 1473979592.762960 $ $ # Modifying an existing file updates both times: $ echo stuff >> foo $ ./pystat.py foo mtime: 1473979622.722959 ctime: 1473979622.722959 $ $ # Changing permissions ONLY updates the ctime: $ chmod 777 foo $ ./pystat.py foo mtime: 1473979622.722959 ctime: 1473979643.542958 $ $ # So does moving a file: $ mv bar baz $ ./pystat.py baz mtime: 1473979592.762960 ctime: 1473979659.586958 $ $ # Consequently, both files now have ctime > mtime $ $ # However, we CAN manually set mtime in the future $ # and thereby cause ctime < mtime: $ touch --date="2041-01-01 12:34:56" foo $ ./pystat.py foo mtime: 2240656496.000000 ctime: 1473989678.258937 

正如@ketil所说,当文件元数据被改变时,ctime被更新。

一种可以改变的方法是,如果你将文件从一个目录移动到另一个目录。 ctime会改变,但不是mtime。

 touch test_file mv test_file another_directory/ stat another_directory/test_file 

  File: `another_directory/test_file' Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 80ah/2058d Inode: 23183108 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 1004/ agrimm) Gid: ( 1004/ agrimm) Access: 2011-07-07 10:11:27.000000000 +1000 Modify: 2011-07-07 10:11:27.000000000 +1000 Change: 2011-07-07 10:11:43.000000000 +1000