by Rde (54 Submissions)
Category: Files/File Controls/Input/Output
Compatability: VB Script
Difficulty: Beginner
Date Added: Wed 3rd February 2021
Rating: (3 Votes)
I have come across several different solutions for testing for a file's existance, from Dir to opening the file, testing for error, then closing the file again. I remembered an article/comment by Bruce McKinney that influenced my solution to this problem and thought I would share it.
The Question of Existence - by Bruce McKinney
Testing for the existence of a file ought to be easy (and is in most
languages), but it turns out to be one of the most annoying problems
in Visual Basic. Don't count on simple solutions like this:
fExist = (Dir$(sFullPath) <> vbNullString)
Dir will return the first file found if you happen to pass sFullPath as
an empty string, and so will set fExist to True. You could use:
If sFullPath <> vbNullString Then fExist = (Dir$(sFullPath) <> vbNullString)
That statement works until you specify a file on an empty floppy or
on a CD-ROM drive. Then you're stuck in a message box.
Here's another common one:
fExist = FileLen(sFullPath)
It fails on 0-length files — uncommon but certainly not unheard of.
My theory is that the only reliable way to check for file existence
in Basic (without benefit of API calls) is to use error trapping.
I've challenged many Visual Basic programmers to give me an
alternative, but so far no joy. Here's the shortest way I know:
Function FileExists(sSpec As String) As Boolean
On Error Resume Next
Call FileLen(sSpec)
FileExists = (Err = 0)
End Function
This can't be very efficient. Error trapping is designed to be fast
for the no fail case, but this function is as likely to hit errors
as not.
Perhaps you'll be the one to send me a Basic-only ExistFile function
with no error trapping that I can't break.
Until then, here's an API alternative:
Function ExistFileDir(sSpec As String) As Boolean
Dim af As Long
af = GetFileAttributes(sSpec)
ExistFileDir = (af <> -1)
End Function
I didn't think there would be any way to break this one, but it turns
out that certain filenames containing control characters are legal on
Windows 95 but illegal on Windows NT. Or is it the other way around?
Anyway, I have seen this function fail in situations too obscure to
describe here.
Bruce McKinney
Please note that the VB6 File System Object's GetAttr function cannot be used in place of the GetFileAttributesA API function in this technique as it raises an error when the path is invalid.
Private Declare Function GetFileAttributes Lib "kernel32" _
Alias "GetFileAttributesA" (ByVal lpSpec As String) As Long
Private Const INVALID_FILE_ATTRIBUTES As Long = -1
Function FileExists(sFileSpec As String) As Boolean
Dim Attribs As Long
Attribs = GetFileAttributes(sFileSpec)
If (Attribs <> INVALID_FILE_ATTRIBUTES) Then
FileExists = ((Attribs And vbDirectory) <> vbDirectory)
End If
End Function
Function DirExists(sPath As String) As Boolean
Dim Attribs As Long
Attribs = GetFileAttributes(sPath)
If (Attribs <> INVALID_FILE_ATTRIBUTES) Then
DirExists = ((Attribs And vbDirectory) = vbDirectory)
End If
End Function