0

I was hoping that just using something like

with open(file_name, "w") as f:

would not change ctime if the file already existed. Unfortunately it does. Is there a version which will leave the ctime intact?

Motivation: I have a file that contains a list of events. I would like to know how old the oldest event is. It seems this should be the files ctime.

Sarien
  • 6,647
  • 6
  • 35
  • 55
  • 1
    You can set the modification time of the newly created file: https://stackoverflow.com/questions/1158076/implement-touch-using-python – hek2mgl Dec 17 '19 at 09:53
  • 1
    @hek2mgl Is ctime in there? I only see atime and mtime. – Sarien Dec 17 '19 at 10:00
  • 1
    Are you sure you are talking about ctime? Most Linux filesystems doesn't expose the ctime – hek2mgl Dec 17 '19 at 10:05
  • @BasileStarynkevitch Okay, maybe I am misunderstanding what ctime does. Would you care to explain? It seems like modification detection should be done using mtime, right? – Sarien Dec 17 '19 at 10:28

4 Answers4

3

Beware, ctime is not the creation time but the inode change time. It is updated each time you write to the file, or change its meta-data, for example rename it. So we have:

  • atime : access time - each time the file is read
  • mtime : modification time - each time file data is change (file is written to)
  • ctime : change time - each time something is changed in the file, either data or meta-data like name or (hard) links

I know no way to reset the ctime field because even utimes and its variant can only set the atime and mtime (and birthtime for file systems that support it like BSD UFS2) - except of course changing the system time with all the involved caveats...

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
1

Because fopen works that way when using 'w' as an option. From the manual:

"w" write: Create an empty file for output operations.
If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file.

If you don't want to create a new file use a+ to append to the file. This leaves the create date intact.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
jared
  • 473
  • 3
  • 16
0

Unfortunately there isn't. All you can do to a file without changing its ctime is to read it. All you could do is setting the ctime, although is is not trivial either. You have to change your systems time, then touch the file and then reset your system time to current time.

Have a look at this and this

Edit:

I'm talking about Unix Systems, as OP stated in the tags

Community
  • 1
  • 1
LeoE
  • 2,054
  • 1
  • 11
  • 29
  • 1
    you _don't_ need to change your system time! https://stackoverflow.com/questions/1158076/implement-touch-using-python – hek2mgl Dec 17 '19 at 09:55
  • 1
    Seems pretty trivial to me: https://stackoverflow.com/a/6107220/3558960 – Robby Cornelissen Dec 17 '19 at 09:58
  • But the question was "without" changing it's ctime, so keeping the ctime from before, not setting the ctime, did I misunderstand something here? – LeoE Dec 17 '19 at 10:05
-1

Motivation: I have a file that contains a list of events. I would like to know how old the oldest event is. It seems this should be the files ctime.

This is a perfect use case for a sqlite database (or perhaps even a PostGreSQL one, if your application can be run either on several Linux hosts -sharing a common database server- or in different Linux processes), or at least a GDBM indexed file. BTW, what exactly is an event for your application, and how is each event represented in the file? If you use any relational database, invest your efforts on designing well enough the database schema, learn about database normalization and cleverly design suitable database indexes.

And I would register each event in that file or database with an explicit event addition time. See time(7) for more.

Maybe you are considering a huge volume of data (many terabytes). Then look also into this answer.

Be aware that your processor is a lot faster than your disk (even an SSD one). In practice, a significant part of your file data may sit in the page cache (so getting more RAM could improve performance significantly).

See also https://www.linuxatemyram.com/ and http://norvig.com/21-days.html for useful insights.

If performance really matters to you, consider recoding your application in some compiled language implementation (C++ with GCC, Rust, Ocaml, SBCL, Go....). Most of them are significantly faster than Python.

Be aware that disk space is cheaper than CPU time, which is cheaper than your developer's time and efforts.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547