2011-01-03 5 views
6

Al usar os.stat() en Python, ¿puedo suponer que st_ctime siempre es inferior o igual a st_mtime? ¿Si no, porque no?¿El tiempo siempre es <= mtime?

El código siempre se ejecutará en Linux, pero si hay una diferencia entre los sistemas operativos, sería bueno saberlo.

+1

Esta pregunta era un poco confusa, y su respuesta aceptada es realmente muy incorrecta. Normalmente 'mtime <= ctime', ¡no al revés! Ver [mi respuesta] (http://stackoverflow.com/a/39521489/1709587) para una explicación y una demostración de esto en el shell. –

+1

'ctime' no es creación en absoluto, es metadata ** change ** time. La respuesta aceptada es total y completamente errónea: no son solo "algunas situaciones" o (de lo contrario, como esa frase implica) casos de esquina raros donde esta suposición es inválida. –

Respuesta

4

hay algunas situaciones en las que este supuesto podría resultar no válida (y dependería en gran medida de la implementación del sistema operativo):

  • zonas horarias. Si crea un archivo en, por ejemplo, UTC + 4, y luego lo modifica cuando la zona horaria actual es UTC-8, y el sistema operativo no utiliza UTC para todas las marcas de tiempo detrás de las escenas, el tiempo modificado será menor que el tiempo creado Sería sorprendente que un sistema operativo moderno (Windows, OSX, uno de los BSD o Linux) tuviera mtime < ctime en este caso.
  • Restableciendo el tiempo del sistema operativo. Esto podría afectar el tiempo modificado para crear esta situación. Yo diría que sería mucho más probable que tuvieras mtime < ctime sin quejas del sistema operativo en este caso, suponiendo que no haya controles en el controlador del sistema de archivos para evitar este caso.
  • Modificar los tiempos mediante llamadas al sistema. Nuevamente, el controlador del sistema de archivos puede tener controles instalados para evitar situaciones inusuales como esta.

Ambos son reproducibles: su mejor opción es tomar una variedad de sistemas operativos que planea enfocar y probar este comportamiento. Todo lo que puedo proporcionar es especulación.

También, st_ctime no es necesariamente el "tiempo creado", sino el momento del "último cambio de estado" (source). utime marca el ctime del archivo que se actualizará (source) y su parámetro de tipo "utimbuf" no tiene ningún miembro para ctime. Por lo tanto, técnicamente es posible que ctime sea un tiempo pasado mtime si el sistema operativo y el sistema de archivos lo permiten. La documentación os.stat realmente menciona esto:

plataforma dependiente; el tiempo de la mayoría reciente cambio de metadatos en Unix, o el tiempo de la creación en Windows

Mientras Python esconde una gran cantidad de la parte C de las cosas, os.stat y amigos están construidos sobre el mismo sistema de base de C llama así la especificación para ellos es un gran lugar para buscar más información.

+0

Creo que lo hiciste al revés en la primera oración, ¿verdad? :-) –

+0

@Lennart: está en lo cierto, ¡corregido! :) –

+1

"algunas situaciones" es un lenguaje muy, muy cauteloso para una suposición que no tiene una base significativa (y generalmente es * lo opuesto * a la situación real, en donde ctime> = mtime). –

3

Es completamente posible establecer ambos valores mediante programación. También es posible que esto suceda "naturalmente" ajustando el reloj nuevamente antes de que se creara el archivo.

En otras palabras, sí. Sería inusual pero es completamente posible.

+0

No conozco ninguna forma de programar el ctime en Unix mediante programación. No sé sobre Windows. De todos modos, ¿podría proporcionar una referencia a la API (s) que está pensando? – Nemo

4

Defina "menos que", ¿quiere decir más reciente o más antiguo? No puede suponer que ctime sucedió antes de mtime, pero normalmente ctime es igual o posterior a mtime.

ctime en Unix no es "crear tiempo", sino "cambiar el tiempo". mtime se actualiza cuando se cambia el contenido de un archivo, pero ctime se actualiza cuando se modifican los metadatos del archivo (lo que significa que se actualiza cuando también se actualiza mtime), por lo que es perfectamente normal que ctime sea posterior a mtime.He aquí un ejemplo:

[email protected]:~$ touch test 
[email protected]:~$ chmod 600 test 
[email protected]:~$ 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 esto es una diferencia entre el sistema operativo Windows y Unix. He leído algo sobre esto en línea, pero te dejaré hacer tu propia investigación sobre esto.

+3

" menos que "siempre es anterior/anterior. –

0

Como dice @ketil, ctime se actualiza cuando se modifican los metadatos de los archivos.

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 
1

Tienes esta al revés! 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 del archivo y mtime es una fecha de modificación del archivo, en Unix son ambas fechas de modificación, con la diferencia de que:

  • mtime se actualiza cada vez que el archivo de contenido cambia
  • ctime se actualiza cada vez que el archivo de atributos cambio, incluyendo su mtime

La página de manual para (al menos algunas variantes de) stat utility se refiere a estos respectivamente como "Hora de la última modificación de datos" y "Hora del último cambio de estado".

Por lo tanto cada vez que mtime se actualiza, ctime también se actualiza. Los únicos mecanismos que conozco por el cual usted podría tener una mtime que es mayor que el ctime son:

Desde lo solicitado en el contexto de Python, vamos a hacer una herramienta de Python simple que da salida a la mtime y ctime de un archivo determinado para ayudarnos a demostrar esto.Vamos a utilizar las convenientes os.path.getctime y os.path.getctime API en nuestro guión, pero utilizando los st_ctime y st_mtime propiedades del resultado de una llamada stat daría exactamente el mismo resultado:

#!/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 ahorrar que a medida que pystat.py, hacen es ejecutable, y experimenta en nuestro shell 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 
Cuestiones relacionadas