Is File Open?

How can I tell if a file is open by another process other than trying to open it and test for an error?
LVL 1
Neal HartmanAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
watyConnect With a Mentor Commented:
On Error Statement Example
This example first uses the On Error GoTo statement to specify the location of an error-handling routine within a procedure. In the example, an attempt to delete an open file generates error number 55. The error is handled in the error-handling routine, and control is then returned to the statement that caused the error. The On Error GoTo 0 statement turns off error trapping. Then the On Error Resume Next statement is used to defer error trapping so that the context for the error generated by the next statement can be known for certain. Note that Err.Clear is used to clear the Err object's properties after the error is handled.

Sub OnErrorStatementDemo()
   On Error GoTo ErrorHandler   ' Enable error-handling routine.
   Open "TESTFILE" For Output As #1   ' Open file for output.
   Kill "TESTFILE"   ' Attempt to delete open
            ' file.
   On Error Goto 0   ' Turn off error trapping.
   On Error Resume Next   ' Defer error trapping.
   ObjectRef = GetObject("MyWord.Basic")   ' Try to start nonexistent
            ' object, then test for
'Check for likely Automation errors.
   If Err.Number = 440 Or Err.Number = 432 Then
      ' Tell user what happened. Then clear the Err object.
      Msg = "There was an error attempting to open the Automation object!"
      MsgBox Msg, , "Deferred Error Test"
      Err.Clear   ' Clear Err object fields
   End If    
Exit Sub      ' Exit to avoid handler.
ErrorHandler:   ' Error-handling routine.
   Select Case Err.Number   ' Evaluate error number.
      Case 55   ' "File already open" error.
         Close #1   ' Close open file.
      Case Else
         ' Handle other situations here...
   End Select
   Resume   ' Resume execution at same line
            ' that caused the error.
End Sub
0
 
watyCommented:
On error goto ERROR_OPEN
nFile = FreeFile
Open sFile For Binary Access Write As #nFile

ERROR_OPEN:
    If Err = 55 then msgbox "File already open"
       
0
 
chabaudCommented:
Use the API function OpenFile with the OF_EXIST style.

Create Form1 with one button named Open, one button Close and one button Test, then paste this code:

Option Explicit

Private Declare Function OpenFile Lib "kernel32" (ByVal lpFileName As String, lpReOpenBuff As OFSTRUCT, ByVal wStyle As Long) As Long

Private Const OF_SHARE_EXCLUSIVE = &H10
Private Const OF_EXIST = &H4000
Private Const OFS_MAXPATHNAME = 128
Private Const HFILE_ERROR = -1
Private Type OFSTRUCT
        cBytes As Byte
        fFixedDisk As Byte
        nErrCode As Integer
        Reserved1 As Integer
        Reserved2 As Integer
        szPathName(OFS_MAXPATHNAME) As Byte
End Type
Private Const theFile = "D:\tmp\toto.txt"

Private Sub Test_Click()
    Dim ofs As OFSTRUCT
    If OpenFile(theFile, ofs, OF_SHARE_EXCLUSIVE Or OF_EXIST) = HFILE_ERROR Then
        MsgBox "Already opened"
    Else
        MsgBox "not opened"
    End If
End Sub

Private Sub Open_Click()
    Open theFile For Random As #1
End Sub

Private Sub Close_Click()
    Close #1
End Sub

0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
vikiingCommented:
Friend Waty: Rmquade is asking for "a process other than trying to open it and test for an error".

Besides that, the code you suggest only checks if file is opened BY THE application ITSELF, and doesn't check for another app..

Rmquade: you have no option. Trying to open the file is the only way to check for it, like this:

    i%=Freefile : on error resume next
    Open <file> for input lock read write as #I% : ser%=err
    close #i%
    If ser%=70 then <permission denied>

If error code is 70, it means file is already opened by an application (perhaps yourself), because you're specifying to block out any other acces, and the only way to achieve that is when file is not in use at all.

   
0
 
watyCommented:
The code I have done check for an opened file by the current process, by the system, or by another process.

Here is a more complet sample :

On Error Statement Example
This example first uses the On Error GoTo statement to specify the location of an error-handling routine within a procedure. In the example, an attempt to delete an open file generates error number 55. The error is handled in the error-handling routine, and control is then returned to the statement that caused the error. The On Error GoTo 0 statement turns off error trapping. Then the On Error Resume Next statement is used to defer error trapping so that the context for the error generated by the next statement can be known for certain. Note that Err.Clear is used to clear the Err object's properties after the error is handled.

Sub OnErrorStatementDemo()
   On Error GoTo ErrorHandler   ' Enable error-handling routine.
   Open "TESTFILE" For Output As #1   ' Open file for output.
   Kill "TESTFILE"   ' Attempt to delete open
            ' file.
   On Error Goto 0   ' Turn off error trapping.
   On Error Resume Next   ' Defer error trapping.
   ObjectRef = GetObject("MyWord.Basic")   ' Try to start nonexistent
            ' object, then test for
'Check for likely Automation errors.
   If Err.Number = 440 Or Err.Number = 432 Then
      ' Tell user what happened. Then clear the Err object.
      Msg = "There was an error attempting to open the Automation object!"
      MsgBox Msg, , "Deferred Error Test"
      Err.Clear   ' Clear Err object fields
   End If  
Exit Sub      ' Exit to avoid handler.
ErrorHandler:   ' Error-handling routine.
   Select Case Err.Number   ' Evaluate error number.
      Case 55   ' "File already open" error.
         Close #1   ' Close open file.
      Case Else
         ' Handle other situations here...
   End Select
   Resume   ' Resume execution at same line
            ' that caused the error.
End Sub


0
 
chabaudCommented:
what about my solution using API ?
0
 
mark2150Commented:
Actually the *BEST* way is to open the file for write and trap the error. If you just *test* the file and do not *GRAB* it for your use then you have no certainty that the result will be valid for any length of time! If you have two competing processes and you do your test and the other does *IT'S* test and you now *BOTH* think you have access to the file and you've reached a condition known as "deadly embrace" where *BOTH* of your processes are cross locked. This is *NOT* the way to safely code multi-user apps.

If you attempt to open the file for WRITE and do *NOT* get the error, then your code can continue to execute, confident that the file is *YOURS ALONE* to manipulate. The requirement "other than trying to open it and test for an error?" will generate *LOCKUPS* in a multi-user environment. The "open it and test for error" method is *CORRECT* and the only way to assure that your code will run no matter how many users are competing for the lock on a standard data file.

M

0
 
vikiingCommented:
Friend Mark: you've said "you now *BOTH* think you have access to the file and you've reached a condition known as "deadly embrace" where *BOTH* of your processes are cross locked"

That's not right. Because BOTH processes will thing file is free, when both try to re-open, only one will gain access, and the other will die with the error "Permission denied".

The main question here was "How to know if a file is already in use", and not "How to gain exclusive access to a file". If the intended purpose is last one, of course, once file was successfuly opened, it must remain so until the end of the process.

0
 
Neal HartmanAuthor Commented:
I guess the I was right in the first place. There are a lot of ways to open and trap for errors but that appears to be the only way.

Thanks Everyone.

0
 
watyCommented:
As I have posted the answer first would you like to agree my answer?
0
 
Neal HartmanAuthor Commented:
Anything for you waty!

0
 
BobsExExCommented:
None of these solutions work for me.  I have tried every one.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.