Sign in to follow this  
Followers 0
Nugit

Behaviour of FindFileFirst/FindFileNext

1 post in this topic

Hello to all the AutoIT communauty,

as you can see, I'm totally new here even if I read this forum for several months with a great pleasure. Until now, I never felt the need to register simply because I always found the answers to my questions on your excellent forum. But, I finally decided to register because I noticed a strange behaviour of the 2 functions FindFileFirst and FileFindNext and I would like to get a confirmation from some experts before doing huge modifications to my code.

So... I built a sort of library with some functions on files management : among those functions, I created a recursive search function in sub-directories. Here is how it works :

FILE_SearchEx($InFilesToSearch, $InDirectoryDepth, $InTrimPath = 0)

$InFilesToSearch : searching criteria : for example : D:\test\*.txt

$InDirectoryDepth : maximum of successive recursive searches that can be done

$InTrimPath (optional) : return full pathes or files names only

Return code : an array with the number of files found in the first element and all files after.

I'll put the code below for you to look at that. I hope I didn't do too many mistakes even if it's working for several months now.

My problem now : if in a same directory, I have 2 files named like that :

- File1.txt

- File2.txt.old

Then the search retrieves me 2 files with the searching criteria above. In my mind, only the "D:\Test\*.txt*" must give such a result. It doesn't seem to be an AutoIT problem because the Visual Basic DIR function works exactly in the same way. Nevertheless, the searching engine of my Windows (2000 version) only give the first file and it seems to me more logical.

So, finally, if you're still here ;), here come my question : is that a smart mean to get an improved filtered result or do I need to check the file extension in the retrieved files with strings functions ?

I hope everything is understandable and that my english is correct enough. :">

Best regards

Here is the code now

; ###########################################################
; # LIB_FILE.AU3
; #
; # V1.0 : Initial revision
; ###########################################################

; ***************************************************
; * INCLUDES
#include-once
#include <lib_types.au3>

; ***************************************************
; * CONSTANTS
; ***************************************************
; * CONSTANTS
; True/false
Const $cFalse = 0
Const $cTrue = 1

; Error codes
Const $cOK = 0
Const $cError = -1

; Search flags
Const $cFILE_SearchPathFull = 0
Const $cFILE_SearchPathNone = 1

; ###########################################################

; ***************************************************
; * FILE_PathComplete()
; * Returns : Completed path
; ***************************************************
Func FILE_PathComplete($InPath)
    If (StringRight($InPath, 1) <> "\") Then
        Return($InPath & "\")
    Else
        Return($InPath)
    EndIf
EndFunc
; ***************************************************

; ***************************************************
; * FILE_SplitFilePath()
; * Returns : -
; ***************************************************
Func FILE_SplitFilePath($InFilePath)
    Local $zSplit, $zInd
    Local $zReturn[2]

   ; Check if the previous extraction wasn't the same
    $zReturn[0] = ""
    $zReturn[1] = ""
    $zSplit = StringSplit($InFilePath, "\")
    If ($zSplit[0] <> 0) Then
       ; Build file path
        For $zInd = 1 To $zSplit[0] - 1
            $zReturn[0] = $zReturn[0] & $zSplit[$zInd] & "\"
        Next
        $zReturn[1] = $zSplit[$zSplit[0]]; Assign file name at same time
    EndIf
    Return($zReturn)
EndFunc
; ***************************************************

; ***************************************************
; * FILE_SearchEx()
; * Returns : Number of files found and list of files
; ***************************************************
Func FILE_SearchEx($InFilesToSearch, $InDirectoryDepth, $InTrimPath = 0)
    Local $zSearchID
    Local $zExitFlag
    Local $zReturn[1], $zReturnRec[1]
    Local $zSplitPath[2], $zRecPath
    Local $zNextFile

   ; Search at the Root directory only first
    $zReturn = FILE_Search($InFilesToSearch, $InTrimPath)
    
   ; Search in sub-directories now if requested
    If ($InDirectoryDepth > 0) Then
        $zSplitPath = FILE_SplitFilePath($InFilesToSearch); Retrieve the current path
        $zSplitPath[0] = FILE_PathComplete($zSplitPath[0])
        SetError($cOK); Clear the error status
        $zSearchID = FileFindFirstFile($zSplitPath[0] & "*.*"); Initialize search
        If ($zSearchID <> $cError) Then
            SetError($cOK); Clear the error status
            $zExitFlag = $cFalse
            While($zExitFlag = $cFalse)
                $zNextFile = FileFindNextFile($zSearchID)
                If (@error <> $cOK) Then
                    $zExitFlag = $cTrue; End of search
                Else
                    $zRecPath = $zSplitPath[0] & $zNextFile
                   ; Start the recursive search if needed
                    If ((FileGetAttrib($zRecPath) = "D") AND _
                        ($zNextFile <> "..") AND _
                        ($zNextFile <> ".")) Then
                        $zRecPath = FILE_PathComplete($zRecPath)
                        $zReturnRec = FILE_SearchEx($zRecPath & $zSplitPath[1], $InDirectoryDepth - 1, $InTrimPath)
                       ; Increase size of final array
                        ReDim $zReturn[$zReturn[0] + $zReturnRec[0] + 1]

                       ; Copy files found in final array
                        For $zInd = 1 To $zReturnRec[0]
                            $zReturn[$zReturn[0] + $zInd] = $zReturnRec[$zInd]
                        Next
                        $zReturn[0] = $zReturn[0] + $zReturnRec[0]
                    EndIf
                EndIf
            WEnd
        EndIf
        FileClose($zSearchID)
    EndIf

    Return($zReturn)
EndFunc
; ***************************************************

; ***************************************************
; * FILE_Search()
; * Returns : Number of files found and list of files
; ***************************************************
Func FILE_Search($InFilesToSearch, $InTrimPath = 0)
    Local $zExitFlag
    Local $zSearchID
    Local $zReturn[1]
    Local $zSplitPath[2]

    $zReturn[0] = 0
    $zSplitPath = FILE_SplitFilePath($InFilesToSearch); Retrieve the current path
    $zSplitPath[0] = FILE_PathComplete($zSplitPath[0])
    SetError($cOK); Clear the error status
    $zSearchID = FileFindFirstFile($InFilesToSearch); Initialize search
    If ($zSearchID <> $cError)  Then
        SetError($cOK); Clear the error status
        $zExitFlag = $cFalse
        While ($zExitFlag = $cFalse)
            $zSplitPath[1] = FileFindNextFile($zSearchID)
            If (@error <> $cOK) Then
                $zExitFlag = $cTrue; End of search
            Else
                $zReturn[0] = $zReturn[0] + 1
                ReDim $zReturn[$zReturn[0] + 1]
                If ($InTrimPath = $cFILE_SearchPathFull) Then
                    $zReturn[$zReturn[0]] = $zSplitPath[0] & $zSplitPath[1]
                Else
                    $zReturn[$zReturn[0]] = $zSplitPath[1]
                EndIf
            EndIf
        WEnd
    EndIf
    FileClose($zSearchID)
    
    Return($zReturn)
EndFunc
; ***************************************************

Share this post


Link to post
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0