Link to home
Start Free TrialLog in
Avatar of BrianBeck
BrianBeck

asked on

VB6 - Making sure that a file is closed

Dear Gurus
I've been encountering a situation where a text file channel, according to VB, is already open.  It occurs about 10% of the time the routine is called. This has given me a rather puzzling problem.  How is it that a 'File already open' error can occur at line #112, given that the file channel would have just been closed??

The size of the files saved is rather small, about 1,000 characters. I've carefully checked through the code in my app:
(i) all references to files make use of the 'intfnum = FreeFile' method, ie, no fixed channel assignments
(ii) files are closed prior to the end of each subroutine
I searched EE and found a suggestion to introduce a small delay, hence the loop below.  I'm not sure if this has made a difference.

Your help in advance is most appreciated.

Private Function DO_THE_FILE_SAVE(ByVal FilePath As String, ByVal s As String)
'11-oct-07, bring it here
Dim intfnum As Integer, FileChannelNumber As Integer
Dim Result As Long, j As Long
     Const procname As String = "DO_THE_FILE_SAVE"
     On Error GoTo Err

100     If IsFileAlreadyOpen(FilePath, s, FileChannelNumber) = -1 Then
            Close #FileChannelNumber 'if the file happens to still be open from a previous operation, close it
        End If
       
104     For j = 1 To 40000 'delay, typically a few hundred milliseconds, so we can try again
            DoEvents
        Next
       
110     intfnum = FreeFile 'a new file handle
112     Open FilePath For Output As #intfnum
114     Print #intfnum, s
116     Close #intfnum
       
120     Exit Function
           
Err:
200     MsgBox "ErrCode: " & Erl & vbCrLf & "Error: " & Err.Description 'File already open' error
End Function

Private Function IsFileAlreadyOpen(ByVal FilePath As String, ByVal s As String, ByRef FileChannelNumber As Integer)
'11-oct-07
Dim intfnum As Integer
     Const procname As String = "IsFileAlreadyOpen"
    On Error GoTo Err
   
100     intfnum = FreeFile
        Open FilePath For Input As #intfnum
        Close #intfnum
        IsFileAlreadyOpen = 0 'ie, ok
        Exit Function
   
Err:
        Select Case Err.number
        Case 55 'thanks EE
            IsFileAlreadyOpen = -1 'error
            FileChannelNumber = intfnum
        End Select
End Function
Avatar of Jai S
Jai S
Flag of India image

you dont need a loop to delay a process - thts called as  BAD practice

use
Sleep(millisecs) instead
and call DoEvents
Sleep(your integer value)
DoEvents
Avatar of BrianBeck
BrianBeck

ASKER

Hi jaiganeshsrinivasan:

Thanks, will do.  Would be happen to know of an answer to the underlying file open problem?
Private Function DO_THE_FILE_SAVE(ByVal FilePath As String, ByVal s As String)
'11-oct-07, bring it here
Dim intfnum As Integer
Dim Result As Long, j As Long
     Const procname As String = "DO_THE_FILE_SAVE"
     On Error GoTo Err

100     while (IsFileAlreadyOpen(FilePath) = -1) Then
            doevents
            Sleep(millisecs) instead  ' suggested by jaiganeshsrinivasan
            Wend
       
110     intfnum = FreeFile 'a new file handle
112     Open FilePath For Output As #intfnum
114     Print #intfnum, s
116     Close #intfnum
       
120     Exit Function
           
Err:
200     MsgBox "ErrCode: " & Erl & vbCrLf & "Error: " & Err.Description 'File already open' error
End Function

Private Function IsFileAlreadyOpen(ByVal FilePath As String)
'11-oct-07
Dim intfnum As Integer
     Const procname As String = "IsFileAlreadyOpen"
    On Error GoTo Err
   
100     intfnum = FreeFile
        Open FilePath For Input As #intfnum
        Close #intfnum
        IsFileAlreadyOpen = 0 'ie, ok
        Exit Function
   
Err:
        Select Case Err.number
        Case 55 'thanks EE
            IsFileAlreadyOpen = -1 'error
        End Select
End Function

Hi EDDYKT:
Thanks, but from what I've seen 'sleeping' or 'waiting' doesnt seem to solve the underlying problem.
Is there some way in which I can brute force delete the existing file (I've already saved the new contents in a string, so once the file is deleted, I'd simply create a new text file with the same name as the original one).
In other words, is there a way to bypass VB's built in open file check, and simply request Windows to delete the file?  I realise that this may be unorthodox, but can it be done?
Brian
ASKER CERTIFIED SOLUTION
Avatar of EDDYKT
EDDYKT
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi EddyKT
Thanks for your suggestions, though as I need an automated, reliable approach, the registry method seems promising.  I'm unsure as to why the file remains open.

Is there a limit to the number of characters in can have in a string?  Can the string have CRLF delimeters?
if you use string value in registry 8192 is max number of char (if i remember correctly)
if you have more than the above number, use expanable string