We have a financial system that writes a text file out that could be several 100 or even 1000 lines long. It writes the file into a txt file and can't be modified to be another file extension and then be renamed after the data has been loaded.
I have a service already written that notices that a txt file has shown up in this directory and fires off the application that needs to read this data.
I don't want to have the application which reads the data begin the process until after the financial system has written all data to the file.
I've searched all kinds of VB help sites and here is the code most refer to in various ways:
Public Function IsFileLocked(filename As String) As Boolean
Dim Locked As Boolean = False
Dim fs As FileStream = File.Open(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)
Catch ex As IOException
Locked = True
I have my file open in Notepad to test and have the file being accessed, but it falls straight through the code and does not hit the catch. I even opened the file in Excel and had the same result.
This method will only work if the file being written by the financial system opens the file for exclusive write, meaning no shared readers or writers. Apparently, the financial system is allowing other processes to write to the file and the same time it's writing it.
The only other way I know of to determine if the file is completely written is to enumerate the system handle table, determine if the file is open currently open and:
1) Keep checking this handle every few seconds and wait for it to disappear. This should signal the end of the file write.
2) Depending on how the file is being written, you may find that the file is being opened, written, then closed, repeatedly. You may have to keep checking and waiting for an arbitrary amount of time to see if the file is again opened before considering the file complete.
I goofed... I was using notepad over and over to try and replicate the file being accessed. I found that notepad doesn't cause the file to show as open. When I tried Excel, right before doing my post, I goofed and opened my output file instead of my input file.
I still need to do some testing when the financial system is writing a file to make sure it works the same way or if I need to take your suggestion and look at the file handle.
Please ignore my post. I was using notepad over and over to try and replicate the file being accessed. I found that notepad doesn't cause the file to show as open. When I tried Excel, right before doing my post, I goofed and opened my output file instead of my input file.
Code works... Thanks to anyone that started researching this issue...
A file being reported as "in use" may even vary on the file-system being used; there is no real way of testing, but trying and recovering if things go wrong.
For reading, that means simply putting up a message that the file is locked by another application which needs to be closed first. For writing, it means (in the ideal case) that one offers a SaveFileDialog to save the file under a new name.
"Testing and opening" is not an option, since it creates a race-condition; the file could be opened between the moment you checked it's status and the moment you're going to lock it.
I agree with everything you said in your reply because each situation you're trying to code for can vary.
In the situation I have however I won't need to worry about the file being re-locked. Basically the financial system writes a report file in text format and the code I posted in the original thread works to check if the file is currently open. Once the financial system has completed the output it will never be opened again except by my application that is picking it up and converting the report to PDF and then deleting the original text file.
My application is executed by a service I wrote that checks if a text file shows up in a certain directory. The service checks every minute. If it sees a text file it executes. My app then goes through the directory and starts reading files for conversion. I don't want to start this process if the financial system has not completed the output, so I'll basically skip if opened and catch it the next time the app executes (1 minute later).
My biggest mistake was assuming notepad would hold the file open for testing....