|
Hi all,
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:
<br />
Public Function IsFileLocked(filename As String) As Boolean<br />
Dim Locked As Boolean = False<br />
Try<br />
Dim fs As FileStream = File.Open(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)<br />
fs.Close()<br />
Catch ex As IOException<br />
Locked = True<br />
End Try<br />
Return Locked<br />
End Function<br />
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.
Any ideas?
Lost in the vast sea of .NET
|
|
|
|
|
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.
Thanks!
Lost in the vast sea of .NET
|
|
|
|
|
I just did testing with the financial system and the code worked without having to go to the file handles.
Thanks again for your reply!
Lost in the vast sea of .NET
|
|
|
|
|
Hi all,
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...
Lost in the vast sea of .NET
|
|
|
|
|
That's because Notepad does not keep the file open as you are editing it. It opens the file, reads the contents, closes the file, then shows you the contents in the window.
Same thing with Excel and reading text files. Excel WILL however, keep a workbook file open for the life of the working session.
modified 14-Nov-12 7:53am.
|
|
|
|
|
KreativeKai wrote: Any ideas?
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....
Lost in the vast sea of .NET
|
|
|
|
|
I had a similar problem and solved it using
Public Function FileInUse(ByVal sFile As String) As Boolean
If System.IO.File.Exists(sFile) Then
Try
Dim F As Short = FreeFile()
FileOpen(F, sFile, OpenMode.Binary, OpenAccess.ReadWrite, OpenShare.LockReadWrite)
FileClose(F)
Catch
Return True
End Try
End If
End Function
usage
Do While FileInUse(sSourcePath & "\" & sFileName & "." & sExtension)
System.Threading.Thread.Sleep(1000)
sTimeOut += 1
If sTimeOut = 15 Then
WriteLogLog("File " & sFile & " in use.")
Exit Sub
End If
Loop
Im testing each second if the file can be opened, if it can't then it is because it is in use. When the loop ends I know my file is no longer in use.
best regards
modified 19-Nov-12 10:20am.
|
|
|
|