How to read (windows) file time, from "Date Modified" property?

Hello all,

I have a case where collision are occuring between my software and anothers. I need to be sure the other is done writing to the file. My thought was to read time part of the last “Date Modified” property, wait for a second or two, then check again to see if it has changed. If it has not, then I would be reasonably assured that the ‘other’ is done.

Can anyone point me to either sample code or any suggested method for doing this? And if anyone has a better idea how to prevent a collision - without the aid of the ‘other’ I would be really appreciative!

Thank you,
Tim

Which OS?

You try to open the file for writing until it works. Only one app does have write access to a file.

The “last modified” date is unreliable for this sort of synchronization. Instead, try to open the file with write permission; under Windows, if the other app isn’t done writing then opening the file should* fail with an IOException.

e.g.

Dim bs As BinaryStream
Dim TheFile As FolderItem
Try
  bs = BinaryStream.Open(TheFile, True) // True=open for writing
  bs.Close() // unless you need to read from it
Catch Err As IOException
  MsgBox("File in use!")
End Try

*It may not fail if the other app specifies an unusually liberal sharing policy when opening the file.

Hi and thanks for the ultra fast reply!

The OS is Win 7. I would be checking every x seconds, and would test at least 3 times, waiting each time for at least 1 to 3 seconds before testing again. With that scenario would it still be unreliable? My problem is, the ‘other’ was supposed to write to a temp file, then fire a batch file. The programmers at the ‘other’ do not want to do their job - it was all documented in this manner. So, I need to find a work around.

Possibly using both the test for I/O error and checking the time may be a good combination?
Again, thank you both for your feedback!
Tim

Why should it matter how often you test? It needs to work for your situation. If the file is relatively small then I don’t see a problem.

If you go this route, then I know some systems wanting to do someting very similar also check for filesize changes.

Hello all,

The filesize is also an excellent idea. The files are text and small - between 1k and 100k. In some cases, they grow fast, in others very slow. I cannot control those things - unfortunately.

But all of these additional tests make sense and can confirm each other as either ready for me, or not - with some reasonable (?) degree of certainty. So everyone does not think I am crazy, the ‘other’ was to do the temp file then fire a batch file renaming the final to something that was ready for me. However… some ‘others’ are more difficult to get to follow the protocol than is really necessary. My customer however, does not care. Just wants results. I am sure we have all been there at one point or another.

Thanks again! Much appreciate the different ideas and input/feedback!
Tim

This is only true if the other app has opened the file for an exclusive write (= denies other processes to write simultaneously).

Another solution might be to opt for notifications that the temporary file has been created, opened, and closed. On OSX this would be the FSEvents class. Would need some declares and testing, but probably the most reliable way to do this. Don’t know what the equivalent in the WinAPI is.

Let us imagine the worst case scenario because “other” did not do according to specs.

You go ahead and write your data. Then the other had started writing without locking (as sloppy as they seem to be) just before, and somehow closes the file after you do. Your write is gone.

I do not see any way to elegantly go around. You should really let the client know he should care about “other” nonchalance because it can and will hurt him.

You should at least obtain from your client that he makes sure that “other” has the elementary courtesy to lock the file when he writes.

If you play by the book, though, you should have incrementals save showing you actually did what you were supposed to do, and that “other” just messed up.

Hi Michael,

I love your reply! No matter how many times I have said the same thing, I get blank stares and basically the attitude if “I don’t want to do it”! Regardless of the agreed spec etc.

The good news is, I read the file, but when I am done with it, I move it to a new location. But that is a problem too, since it does not really move or only moves the part that I have read, since it is still being written.

Regardless, it is a real PIA. Not my fault, is my problem.
Tim

[quote=206567:@Tim Seyfarth]Hi Michael,

I love your reply! No matter how many times I have said the same thing, I get blank stares and basically the attitude if “I don’t want to do it”! Regardless of the agreed spec etc.

The good news is, I read the file, but when I am done with it, I move it to a new location. But that is a problem too, since it does not really move or only moves the part that I have read, since it is still being written.

Regardless, it is a real PIA. Not my fault, is my problem.
Tim[/quote]

I have no idea what kind of business it is, but in all my professional life, whenever I said yes and really felt in my gut I should have said no, I got badly bitten.

If you do what they ask and there is a collision with consequences, you will be blamed, when in fact “other” sloppiness is the culprit.

Sometimes, things are simply not possible if others don’t do what is required. Blank stare or not. Of course, that means simply saying no to a potentially important client. But on the other hand, that maybe enough to wake them up to the security flaw they have in their system. Or have them sign a discharge that they know the consequences.

Exclusive write access is the default behavior. The app would have to explicitly specify shared write access when opening the file. If need be, you could use declares to open the file and specify fully exclusive access (read, execute, etc, in addition to write); if the file is already open, even with shared access, then trying to open it exclusively will fail.

It sounds like the problem is that you’re just reading the file, not writing it. If so, I would recommend reading the file via a BinaryStream, and not a TextInputStream. The reason being, the BinaryStream will attempt to lock the file if you pass True to the Open method. That will throw an exception if the file is still being written to. It will also prevent the other software from writing to the file while you are using it.

I assume the other app is not written in Xojo. If it is for example written in C, there is no default behavior with fopen. Same for WinAPI’s CreateFile. And so on…

Hello Eli

My app is written in Xojo.
Tim

I assumed as much too.

You must specify the share mode to CreateFile. If you don’t, then the default behavior (exclusive access) will be used.

From the CreateFile documentation:

[quote]
If this parameter [sharemode] is zero and CreateFile succeeds, the file or device cannot be shared and cannot be opened again until the handle to the file or device is closed. […] You cannot request a sharing mode that conflicts with the access mode that is specified in an existing request that has an open handle.[/quote]

I don’t think fopen supports sharing in the first place, but I don’t know; I would assume that it acts like CreateFile with no sharemode.

So far as I understand this…

If open for write by Xojo does it demanding exclusive access, then the test code supplied earlier by

will work fine… it’s open won’t succeed if another process has the file open for write, exclusively or not as it cannot get an exclusive lock.

If Xojo does not demand a exclusive access for write, then the a similar test can be done with a couple of declares to open for exclusive write, then closing.

By this thread really caught on!
There are lots of cool ways to do the task. But the best way, is to get ‘other’ to do their job. Finally made that happen. However, I still think I will need to incorporate some or all of these anyway - just in case!

Tim

Tim, have you tried the “open for write access” approach? Either via BinaryStream or declares? (Or even TextOutputStream in Append mode.)

You have implied, but not explicitly stated, that you are reading the file only. Is that accurate? We all seem to be making a lot of assumptions in this thread.

[quote=206685:@Tim Seyfarth]By this thread really caught on!
There are lots of cool ways to do the task. But the best way, is to get ‘other’ to do their job. Finally made that happen. However, I still think I will need to incorporate some or all of these anyway - just in case!

Tim[/quote]

Tim Hare’s suggestion to use BinaryStream seems the best, easily waring against a possible collision, as blocking write on “other” side. If these people are as sloppy as you describe, they may not even have anything to manage a locked file :wink: