Send a suggestion!

We're building a brand new version of the site, and we'd love to hear your ideas

Members

Technology Zones

IBM Learning Center

Articles

Hosted By

MaximumASP

Info

Rated
Read 47,377 times

Contents

Related Categories

Advanced Files & Folders - Does it exist?

Does it exist?

Nearly everyone has used the Dir function in VB, and nearly everyone has been disappointed. It can be very slow (when used in loops), and produces unreliable results when used on a network. A much better way is to use the FindFirstFile and FindNextFile windows api calls. To try this out, add the following code to a module

Option Explicit
Public Const MAX_PATH = 260
Private Const ERROR_NO_MORE_FILES = 18&
Private Const FILE_ATTRIBUTE_DIRECTORY = &H10
Private Const FILE_ATTRIBUTE_NORMAL = &H80
Private Const FILE_ATTRIBUTE_HIDDEN = &H2
Private Const FILE_ATTRIBUTE_SYSTEM = &H4
Private Const FILE_ATTRIBUTE_TEMPORARY = &H100

Private Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type
Private Type WIN32_FIND_DATA
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    nFileSizeHigh As Long
    nFileSizeLow As Long
    dwReserved0 As Long
    dwReserved1 As Long
    cFileName As String * MAX_PATH
    cAlternate As String * 14
End Type

Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" _
    (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long

Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" _
    (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long

Function StripTerminator(ByVal strString As String) As String
    Dim intZeroPos As Integer
    intZeroPos = InStr(strString, Chr$(0))
    If intZeroPos > 0 Then
        StripTerminator = Left$(strString, intZeroPos - 1)
    Else
        StripTerminator = strString
    End If
End Function

Function FileOrDirExists(Optional ByVal sFile As String = "", _
        Optional ByVal sFolder As String = "") As Boolean

    Dim lpFindFileData As WIN32_FIND_DATA, lFileHdl  As Long
    Dim sTemp As String, sTemp2 As String, lRet As Long, iLastIndex  As Integer
    Dim sPath As String
    Dim sStartDir As String
    
    On Error Resume Next
    '// both params are empty
    If sFile = "" And sFolder = "" Then Exit Function
    '// both are full, empty folder param
    If sFile <> "" And sFolder <> "" Then sFolder = ""
    If sFolder <> "" Then
        '// set start directory
        sStartDir = sFolder
    Else
        '// extract start directory from file path
        sStartDir = Left$(sFile, InStrRev(sFile, ""))
        '// just get filename
        sFile = Right$(sFile, Len(sFile) - InStrRev(sFile, ""))
    End If
    '// add trailing to start directory if required
    If Right$(sStartDir, 1) <> "" Then sStartDir = sStartDir & ""
    
    sStartDir = sStartDir & "*.*"
    
    '// get a file handle
    lFileHdl = FindFirstFile(sStartDir, lpFindFileData)
    
    If lFileHdl <> -1 Then
        If sFolder <> "" Then
            '// folder exists
            FileOrDirExists = True
        Else
            Do Until lRet = ERROR_NO_MORE_FILES
                strPath = Left$(sStartDir, Len(sStartDir) - 4) & ""
                '// if it is a file
                If (lpFindFileData.dwFileAttributes And FILE_ATTRIBUTE_NORMAL) = vbNormal Then
                    sTemp = StrConv(StripTerminator(lpFindFileData.cFileName), vbProperCase)
                    '// remove LCase$ if you want the search to be case sensitive (unlikely!)
                    If LCase$(sTemp) = LCase$(sFile) Then 
                        FileOrDirExists = True '// file found
                        Exit Do
                    End If
                End If
                '// based on the file handle iterate through all files and dirs
                lRet = FindNextFile(lFileHdl, lpFindFileData)
                If lRet = 0 Then Exit Do
            Loop
        End If
    End If
    '// close the file handle
    lRet = FindClose(lFileHdl)
End Function

Now add a command button to a form, and add the following code

Private Sub Command1_Click()
    '// test if file exists
    If FileOrDirExists("c:\temp.txt") Then
        Msgbox "The file 'C:\temp.txt' exists"
    Else
        Msgbox "The file 'C:\temp.txt' does not exist"
    End If

    '// test if folder exists
    If FileOrDirExists(,"c:\test directory") Then
        Msgbox "The folder 'c:\test directory' exists"
    Else
        Msgbox "The folder 'c:\test directory' does not exist"
    End If
End Sub

James first started writing tutorials on Visual Basic in 1999 whilst starting this website (then known as VB Web). Since then, the site has grown rapidly, and James has written numerous tutorials, articles and reviews on VB, PHP, ASP and C#. In October 2003, James formed the company Developer Fusion Ltd, which owns this website, and also offers various development services. In his spare time, he's a 3rd year undergraduate studying Computer Science in the UK. He's also a Visual Basic MVP.

Comments

  • Re: [38] Advanced Files &amp; Folders

    Posted by unitled on 28 Jul 2006

    Okay, I've used the 'List all files in a directory' code (with a few slight modifications) but whenever I reboot the computer, it stops finding the files that are there (other than that, it works fine...

  • Posted by HyperHacker on 26 Nov 2004

    I think you use the FOF_SILENT flag. Been a while since I did it though.

  • Posted by HyperHacker on 26 Nov 2004

    I think you use the FOF_SILENT flag. Been a while since I did it though.

  • How does one actually Undo?

    Posted by vor0nwe on 22 Sep 2004

    Hi,

    This code snippet works all right. What I’m looking for, however, is how to actually Undo a file operation? I can’t find any way to do that by code...

    Thanks for all tips!

    vor0nwe

  • Minor bugs

    Posted by RobCrombie on 08 Aug 2004

    Hi,
    Couple of small bugs -

    Change Dim sPath As String to strPath

    Change "" to "\" in two lines -
    sStartDir = Left$(sFile, InStrRev(sFile, ""))
    '// just get filename
    ...