0

I'd like to get a file last modified time in Delphi.

Normally something like FileAge() would do the trick, only the problem is: if I overwrite *File A* with File B using CopyFile, File A's modified date is not updated with current overwrite time as it should(?)

I get that: CopyFile also copy file attributes, but I really need to get the modified date that also works when a file is overwritten.

Is there such function? My whole application relies on modification time to decide whether or not I should proceed with files!


EDIT Just to clarify: I'm only monitoring the files. It's not my application who's modifying them.

TheDude
  • 3,045
  • 4
  • 46
  • 95
  • don't use CopyFile,delete file A and create file B again. – opc0de Jan 23 '13 at 19:31
  • I would use Windows Shell way with using of `SHFileOperation`. – TLama Jan 23 '13 at 19:33
  • I can't, I'm only monitoring the files. It's not me who's modifying them, but I still need to track changes :( – TheDude Jan 23 '13 at 19:34
  • What does the create time returns for overwritten files? – ESG Jan 23 '13 at 19:40
  • Your question edit is then against the initial question. So you're just monitoring files and once you detect file change, you want to change the file's modified date ? – TLama Jan 23 '13 at 19:40
  • @TheVedge: I tried that: creation date is only good when *creating* a file, not overwriting it – TheDude Jan 23 '13 at 19:42
  • @TLama: No, I want to `get` the modified file's date, not change it – TheDude Jan 23 '13 at 19:43
  • Now I see. You're trying to monitor changes based on the modified date/time value and some foreign app uses `CopyFile` which doesn't update this value. This way is not safe if you're going to monitor changes by that. Imagine, that I can modify just this date/time in my file manager without actually changing the file content. In that case your application might be mislead by that. – TLama Jan 23 '13 at 19:47
  • @TLama: Exactly yes. I explained the [reason why I chose this approach here](http://stackoverflow.com/questions/14487764/delphi-overwrite-file-and-wrong-modified-date-time#comment20189042_14487982), I'm hoping to be able to have both the ability to catch large changes *and* reliably get the modification time at the same time. – TheDude Jan 23 '13 at 19:51
  • @TheVedge `CreateTime` get's totally wrong in this case -> http://support.microsoft.com/kb/172190/en-us (btw still the same with W7) – Sir Rufo Jan 23 '13 at 20:24

1 Answers1

1

The documentation for CopyFile says:

File attributes for the existing file are copied to the new file.

Which means that you cannot use base your program on the last modified attribute of the file, or indeed any attribute of the file. Indeed there are all sorts of ways for the last modified attribute of the file to change. It can in fact go backwards in time.

Instead I suggest that you use ReadDirectoryChangesW to keep track of modifications. That will allow you to receive notifications whenever a file is modified. You can write your program in an event based manner based on the ReadDirectoryChangesW API.

If you can't use ReadDirectoryChangesW and the file attributes, then you'll have to base your decisions on the contents of the file.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Yes, I'm well aware of that and I specifically mentioned it in my question. I also *do* use `ReadDirectoryChangesW` (nice catch), but this doesn't `scale`: if a user is copying (or overwriting) a large folder (1000s files), the only way to catch all changes is to `scan` the folder itself instead of dealing with files one by one. That's why I was/am relying on the file modification to catch changes in the event of a large change. – TheDude Jan 23 '13 at 19:48
  • Overwriting a folder containing 1000 files is not an extreme/unusual case. I have to handle this! – TheDude Jan 23 '13 at 19:53
  • I don't know what you mean when you say that `ReadDirectoryChangesW` does not scale. If you would rather carry on using the last modified attribute, as you seem to indicate in that comment, then I don't really see the point of the question. – David Heffernan Jan 23 '13 at 19:53
  • According to my tests `ReadDirectoryChangesW` will not catch every change *if* a user is overwriting a large folder containing 1000s files, that's what I meant by scaling. – TheDude Jan 23 '13 at 19:56
  • Of course no I don't want to keep using the last modified attribute since clearly it's not reliable at all, but I *do* want to rely on something that can track (relatively) large changes, thus my question. – TheDude Jan 23 '13 at 19:58
  • @TheDude If you have problems with `ReadDirectoryChanges` then you should ask about that (and post some code too) – Sir Rufo Jan 23 '13 at 20:17
  • @SirRufo: I don't have issues with `ReadDirectoryChanges`, I actually use it just fine, I just said that using it to track individual files doesn't scale. That's why I relied on file modification date attribute, which lead me to the issue that I discovered, thus my question if there's a reliable way to get file modified time – TheDude Jan 23 '13 at 21:36
  • @TheDude I think ReadDirectoryChanges is flaky for network volumes when connections may be lost. But I don't see why it can't work reliably for large volumes of files. – David Heffernan Jan 23 '13 at 21:39
  • @DavidHeffernan: Regarding `ReadDirectoryChangesW`, if there are too many changes in a short period of time (which inevitably happen if you overwrite a folder containing a lot of files, for instance), I start getting ERROR_NOTIFY_ENUM_DIR (which means: `A notify change request is being completed and the information is not being returned in the caller's buffer. The caller now needs to enumerate the files to find the changes`). In my experience, too many change notifications not dealt with fast enough leads to this. – TheDude Jan 23 '13 at 22:02
  • As I said, using `ReadDirectoryChangesW` to track folder changes and scanning the modified folders is immune to the problem above, but now I see that I can't rely on file modification attribute either, which brings me back to square one :( – TheDude Jan 23 '13 at 22:04
  • I'm still reading [this article](http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html) (which also link to [this post](http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/4465cafb-f4ed-434f-89d8-c85ced6ffaa8/)) that mention [Change Journal](http://msdn.microsoft.com/en-us/library/windows/desktop/aa363798(v=vs.85).aspx), I'm still reading this, but for anyone being in the same situation (ie. `ReadDirectoryChangesW` lost notifications), this may help – TheDude Jan 23 '13 at 22:24
  • OK, I posted a question about [change journal](http://stackoverflow.com/questions/14496630/implement-change-journal-in-delphi) (which probably is the way to go to avoid the file modif. mess), if anyone can help, please share the wisdom! – TheDude Jan 24 '13 at 08:16