Cuando uso os.stat () en Python, ¿puedo asumir que st_ctime siempre es menor o igual que st_mtime? ¿Si no, porque no?
El código siempre se ejecutará en Linux, pero si hay una diferencia entre los sistemas operativos, sería bueno saberlo.
Hay algunas situaciones en las que esta suposición podría resultar inválida (y dependería mucho de la implementación del SO):
Ambos son reproducibles: su mejor opción es tomar una variedad de sistemas operativos que planea orientar y probar este comportamiento. Todo lo que puedo proporcionar es especulación.
Además , st_ctime no es necesariamente el “tiempo creado”, sino el tiempo del “último cambio de estado” ( fuente ). utime
marca el ctime
del archivo que se actualizará ( fuente ) y su parámetro de tipo “utimbuf” no tiene ningún miembro para ctime
. Por lo tanto, es técnicamente posible que ctime sea un tiempo pasado mtime si el sistema operativo y el sistema de archivos lo permiten. La documentación de os.stat
realidad menciona esto:
dependiente de la plataforma hora del cambio de metadatos más reciente en Unix, o la hora de creación en Windows
Mientras Python oculta gran parte del lado C de las cosas, os.stat
y sus amigos se basan en las mismas llamadas al sistema base C, por lo que la especificación para ellos es un gran lugar para buscar más información.
Es totalmente posible establecer ambos valores programáticamente. También es posible que esto suceda “naturalmente” al volver a configurar el reloj antes de crear el archivo.
En otras palabras, sí. Sería inusual pero es totalmente posible.
Por favor, defina “menos que”, ¿quiere decir más nuevo o más viejo? No puede asumir que el ctime ocurrió antes de mtime, pero normalmente ctime es lo mismo que, o después, mtime.
ctime en unix no es “crear tiempo”, sino “cambiar tiempo”. mtime se actualiza cuando se cambia el contenido de un archivo, pero ctime se actualiza cuando se cambian los metadatos del archivo (lo que significa que se actualiza cuando mtime también se actualiza), por lo que es perfectamente normal que ctime esté después de mtime. Aquí hay un ejemplo:
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
Además, creo que en Windows, el campo ctime en realidad significa “crear tiempo”, y que esta es una diferencia de sistema operativo entre Windows y Unix. He leído algo sobre esto en línea, pero te dejaré hacer tu propia investigación sobre esto.
¡Te has equivocado de camino! En Linux (o Mac, o cualquier otro sistema Unix), ctime
normalmente siempre será MÁS TARDE que mtime
, no antes. A diferencia de Windows, donde ctime
es una fecha de creación de archivo y mtime
es una fecha de modificación de archivo, en Unix ambas son fechas de modificación, con la diferencia de que:
mtime
se actualiza cada vez que cambia el contenido del archivo ctime
se actualiza cada vez que cambian los atributos del archivo, incluido su mtime
La página del manual para (al menos algunas variantes de) la utilidad de stat
refiere a estos respectivamente como “Tiempo de la última modificación de datos” y “Tiempo de último cambio de estado” .
Así, cada vez que mtime
se actualiza, ctime
también se actualiza. Los únicos mecanismos que conozco para poder obtener un mtime
mayor que el ctime
son:
mtime
para que sea en el futuro usando las llamadas del sistema utime
o utimes
, o una utilidad que las use como touch -d
Ya que ha preguntado en el contexto de Python, hagamos una herramienta Python simple que mtime
y ctime
de un archivo dado para ayudarnos a demostrar esto. Usaremos las convenientes API os.path.getctime
y os.path.getctime
en nuestro script, pero usar las propiedades st_ctime
y st_mtime
del resultado de una llamada a stat
daría exactamente los mismos resultados:
#!/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))
Podemos guardar eso como pystat.py
, hacerlo ejecutable y experimentar en nuestro shell de Unix:
$ # 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
Como dice @ketil, ctime se actualiza cuando se cambian los metadatos del archivo.
Una forma en que esto puede cambiar es que si mueve un archivo de un directorio a otro. ctime cambiará, pero no mtime.
touch test_file mv test_file another_directory/ stat another_directory/test_file
da
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