0
\$\begingroup\$

I needed a method to test whether a given file is in use. Is the code below up to the task?

Public Function IsFileInUse(path As String) As Boolean
    If IO.File.Exists(path) Then
        Try
            Using fs = IO.File.OpenWrite(path)
                'If stream can write to the file, it suggests the file is not in use.
                Return Not fs.CanWrite
            End Using
        Catch ex As Exception
            'An exception was raised when trying to create a write stream
            'This suggests the file is in use.
            Return True
        End Try
    Else
        'File does not exists, therefore it is not in use:
        'a file could be written anew to the provided path.
        Return False
    End If
End Function
\$\endgroup\$
2
\$\begingroup\$

You should first ask yourself, why do you write a method to check if a file is in use.

You can't use this method to avoid exceptions, because although your method returns False just a microsecond later the file could be opened exclusivly by another program. You still would need to do any file operation inside a Try..Catch block. So the best way would be to do just that.


Looking at your code, I would suggest to use a guard condition to save one level of indentation like so

If Not IO.File.Exists(path) Then 
    Return False
End If
Try....

Using File.OpenWrite(string) would be enough because the only difference to Open(FileMode, FileAccess, FileShare) would be the FileMode value having FileMode.OpenOrCreate and the FileAccess value having FileAccess.Write

If you want to go the way you have posted as answer you could omit the FileAccess.ReadWrite and FileShare.None enumeration because the Open(FileMode) method just calls the overloaded Open(FileMode, FileAccess, FileShare) method with the same values as your call.

What I like about your code is that you apply the .NET Naming GuideLine and your using of the Using to make sure that the stream is closed properly.

What I dislike is that you don't check wether path is null. Proper method parameter validation for public methods should always be done.

\$\endgroup\$
  • \$\begingroup\$ Sorry for taking long to come back. I will adopt your suggestions. I need this method because I'm using EWS Managed API for sending e-mails with preset text but variable attachments, and my users are attaching Word and Excel documents which are in use, which makes EWS libraries to throw ugly exceptions. I want to ding and tell them not to do so :-) \$\endgroup\$ – VBobCat Sep 19 '17 at 13:03
0
\$\begingroup\$

These are the modifications I made based on Andrew Mortimer's and Heslacher's indications:

Public Function IsFileInUse(path As String) As Boolean
    If path Is Nothing Then
        Throw New ArgumentNullException("path")
        Return False
    Else
        If IO.File.Exists(path) Then
            Dim fi = New IO.FileInfo(path)
            Try
                Using fs = fi.OpenWrite
                    Return Not fs.CanWrite
                End Using
            Catch
                Return True
            End Try
        Else
            Return False
        End If
    End If
End Function
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.