Jump to content

RecFileListToArray - Deprecated


Melba23
 Share

Recommended Posts

I would imagine you do not need to test. I did a manual copy of another users directory that was getting the same problem to another share.

Original share: linxux/netware/cifs - produced the self referencing loop

New share: windows/active directory share - produced the correct number of files/folders - no loops

So, unless you want to support file shares on essentially deprecated technology - your function works as designed.

Leaving in the one liner to specifically exclude folders named . and .. from being actioned is probably good error control even though a standard windows share would likely never run up against it.

Link to comment
Share on other sites

  • Moderators

z0iid,

Thanks for testing that - I will keep it in mind for the next update. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • 1 month later...

#include <File.au3>
#include <RecFileListToArray.au3>
Global $Dir[20]
$Dir[0] = "d:Misc"
$Dir[1] = ""
$Dir[2] = ""
For $i = 0 To UBound($Dir) - 1
    If $Dir[$i] = "" Then ContinueLoop
    _Search($Dir[$i], 0)
    _Search($Dir[$i], 1)
Next
Func _Search($Dir, $iRecursion)
    $aFiles = _RecFileListToArray($Dir, "*.jpg; *.png; *.gif", 1, $iRecursion, 0, 2, "", "")
    If Not IsArray($aFiles) Then
        MsgBox(16, "Error", "Invalid input path"& @CRLF & $Dir)
        Return
    Else
        If $iRecursion = 0 Then
            $hFile = FileOpen(@ScriptDir & "1.txt",1)
        Else
            $hFile = FileOpen(@ScriptDir & "2.txt",1)
        EndIf
        _FileWriteFromArray($hFile, $aFiles, 1)
        FileClose($hFile)
    EndIf
EndFunc

extension mask doesn' work. help please

Link to comment
Share on other sites

  • Moderators

address,

Your script as posted run on one of my folders returns the correct number of files of all requested types in both simple and recursive modes. What exactly does not work for you? Do you get any files returned? Only some? :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

address,

First time I have ever fixed anything by merely saying that "it works for me"! ;)

Glad you got it working now. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

#include <RecFileListToArray.au3>
#include <File.au3>
    $aFiles = _RecFileListToArray("d:Misc", "*.jpg; *.png; *.gif", 1, 0, 0, 2, "", ""); second number with or without subfolders
  
  
           $hFile = FileOpen(@ScriptDir & "1.txt",1)
        _FileWriteFromArray($hFile, $aFiles, 1)
        FileClose($hFile)

Can you show me please an example, how do I exclude two folders from my big folder?

If I exclude them, files from these subfolders won't show up in search?

Link to comment
Share on other sites

  • Moderators

address,

If you want to exclude folders then you need to use the "files and folders" return option - that is the only one which honours the $sExclude_List_Folder list. So if you have a folder tree like this:

Test-|
     |-First Folder
     |
     |-Second Folder
     |
     |-Third Folder
     |
     |-Fourth Folder

this code will search in all folders other than "Second Folder" and "Third Folder":

$aList = _RecFileListToArray("N:Test", "*.*", 0, 1, 0, 1, "", "Second Folder;Third Folder")

I mentioned above that you need to use the "files and folders" search option to get the $sExclude_List_Folder parameter to work. If you notice I have added a "" at the end of the initial path - that means that all folders returned by the UDF also end in "". So you can very easily ignore them when you loop through the array reading the file names. ;)

All clear? :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Melba23

This gave me empty txt file

#include <RecFileListToArray.au3>
#include <File.au3>
    $aFiles = _RecFileListToArray("d:MiscPics", "*.jpg; *.png; *.gif", 0, 1, 0, 2, "", "d:MiscPicsOld comp"); second number with or without subfolders
  
  
           $hFile = FileOpen(@ScriptDir & "1.txt",1)
        _FileWriteFromArray($hFile, $aFiles, 1)
        FileClose($hFile)

;$aList = _RecFileListToArray("N:Test", "*.*", 0, 1, 0, 1, "", "Second Folder;Third Folder")
;I mentioned above that you need to use the "files and folders" search option to get the $sExclude_List_Folder parameter to work.
;If you notice I have added a "" at the end of the initial path - that means that all folders returned by the UDF also end in "".
; So you can very easily ignore them when you loop through the array reading the file names.
Link to comment
Share on other sites

  • Moderators

address,

Try this: :)

$aFiles = _RecFileListToArray("d:MiscPics", "*.jpg; *.png; *.gif", 0, 1, 0, 2, "", "Old comp")

You only need the folder name, not the complete path. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

address,

My pleasure. :)

I am afraid you cannot mask by size. You would need to loop through the array of all files produced by _RecFileListToArray and use FileGetSize on each one. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • 3 weeks later...

@Melba23

Is possible to get some kind of progress bar in that udf? I'm trying to do that, in my case i want to search by file search by extension on the whole hard drive. The search work good but as you can image the function take some minute to retrive the resoult. That's why i want to add a simple progress bar, something like:

($Current_Number_Of_Searched_File * 100)/$Total_File_on_HD

But i have no idea on how to set that code in your udf :oops:

Hi and thank's for the help :bye:

Link to comment
Share on other sites

  • Moderators

StungStang,

The UDF returns nothing until it has completed its search so there is no possibility of using it to run a progress bar at present.

Anyway as you would need to run some kind of recursive search on the path to find the total number of files to use as a base value before running the UDF to search the drive, you would effectively be running the UDF twice to produce a progress bar - not very efficient. :bye:

I would suggest using a marquee type progress so that at least the user knows that something is going on: :doh:

#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>

$hGUI = GUICreate("Test", 500, 500)
GUICtrlCreateProgress(10, 10, 400, 20, $PBS_MARQUEE)
GUICtrlSendMsg(-1, $PBM_SETMARQUEE, True, 50) ; final parameter is update time in ms
GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

I hope that helps. :oops:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I think that i've found a working soluction:

This is the new code:

Func _RecFileListToArray($sInitialPath, $sInclude_List = "*", $iReturn = 0, $iRecur = 0, $iSort = 0, $iReturnPath = 1, $sExclude_List = "", $sExclude_List_Folder = "", $sTotal_File = 0, $sProgress = "")

Local $asReturnList[100] = [0], $asFileMatchList[100] = [0], $asRootFileMatchList[100] = [0], $asFolderMatchList[100] = [0], $asFolderSearchList[100] = [1]
Local $sFolderSlash = "", $iMaxLevel, $sInclude_File_Mask, $sExclude_File_Mask, $sInclude_Folder_Mask = ".+", $sExclude_Folder_Mask = ":"
Local $hSearch, $fFolder, $sRetPath = "", $sCurrentPath, $sName
Local $asFolderFileSectionList[100][2] = [[0, 0]], $sFolderToFind, $iFileSectionStartIndex, $iFileSectionEndIndex
Global $sCurrent_File = 0

; Check for valid path
If Not FileExists($sInitialPath) Then Return SetError(1, 1, "")
; Check if folders should have trailing \ and ensure that initial path does have one
If StringRight($sInitialPath, 1) = "\" Then
$sFolderSlash = "\"
Else
$sInitialPath = $sInitialPath & "\"
EndIf
; Add path to folder search list
$asFolderSearchList[1] = $sInitialPath

; Check for valid recur value
If $iRecur > 1 Or Not IsInt($iRecur) Then Return SetError(1, 4, "")
; If required, determine \ count for max recursive level setting
If $iRecur < 0 Then
StringReplace($sInitialPath, "\", "", 2)
$iMaxLevel = @extended - $iRecur
EndIf

; Create Include mask for files
If $sInclude_List = "*" Then
$sInclude_File_Mask = ".+"
Else
If Not _RFLTA_ListToMask($sInclude_File_Mask, $sInclude_List) Then Return SetError(1, 2, "")
EndIf
; Set Include mask for folders
Switch $iReturn
Case 0
; Folders affected by mask if not recursive
Switch $iRecur
Case 0
; Folders match mask for compatibility
$sInclude_Folder_Mask = $sInclude_File_Mask
;Case Else
; All folders match
EndSwitch
;Case 1
; All folders match
Case 2
; Folders affected by mask
$sInclude_Folder_Mask = $sInclude_File_Mask
EndSwitch

; Create Exclude List mask for files
If $sExclude_List = "" Then
$sExclude_File_Mask = ":" ; Set unmatchable mask
Else
If Not _RFLTA_ListToMask($sExclude_File_Mask, $sExclude_List) Then Return SetError(1, 7, "")
EndIf
; Set Exclude mask for folders
Switch $iReturn
Case 0
; Folders affected by mask if not recursive
Switch $iRecur
Case 0
; Folders match mask for compatibility
$sExclude_Folder_Mask = $sExclude_File_Mask
Case Else
; Exclude defined folders as set in extended
If $sExclude_List_Folder <> "" Then
If Not _RFLTA_ListToMask($sExclude_Folder_Mask, $sExclude_List_Folder) Then Return SetError(1, 8, "")
EndIf
EndSwitch
;Case 1
; All folders match
Case 2
; Folders affected by normal mask
$sExclude_Folder_Mask = $sExclude_File_Mask
EndSwitch

; Verify other parameters
If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(1, 3, "")
If Not ($iSort = 0 Or $iSort = 1 Or $iSort = 2) Then Return SetError(1, 5, "")
If Not ($iReturnPath = 0 Or $iReturnPath = 1 Or $iReturnPath = 2) Then Return SetError(1, 6, "")

; Search within listed folders
While $asFolderSearchList[0] > 0

; Set path to search
$sCurrentPath = $asFolderSearchList[$asFolderSearchList[0]]

; Reduce folder search list count
$asFolderSearchList[0] -= 1

; Determine return path to add to file/folder name
Switch $iReturnPath
; Case 0 ; Name only
; Leave as ""
Case 1 ;Relative to initial path
$sRetPath = StringReplace($sCurrentPath, $sInitialPath, "")
Case 2 ; Full path
$sRetPath = $sCurrentPath
EndSwitch

; Get search handle
$hSearch = FileFindFirstFile($sCurrentPath & "*")
; If sorting files and folders with paths then store folder name and position of associated files in list
If $iReturn = 0 And $iSort And $iReturnPath Then
_RFLTA_AddToList($asFolderFileSectionList, $sRetPath, $asFileMatchList[0] + 1)
EndIf
; If folder empty move to next in list
If $hSearch = -1 Then
ContinueLoop
EndIf

; Search folder
While 1
If $sTotal_File > 0 And $sProgress <> "" Then _RFLTA_Progress($sProgress,$sTotal_File)
$sName = FileFindNextFile($hSearch)
; Check for end of folder
If @error Then
ExitLoop
EndIf
;
; Set subfolder flag - @extended set in 3.3.1.1 +
$fFolder = @extended

; If folder then check whether to add to search list
If $fFolder Then
Select
Case $iRecur < 0 ; Check recur depth
StringReplace($sCurrentPath, "\", "", 0, 2)
If @extended < $iMaxLevel Then
ContinueCase ; Check if matched to masks
EndIf
Case $iRecur = 1 ; Full recur
If Not StringRegExp($sName, $sExclude_Folder_Mask) Then ; Add folder unless excluded
_RFLTA_AddToList($asFolderSearchList, $sCurrentPath & $sName & "\")
EndIf
; Case $iRecur = 0 ; Never add
; Do nothing
EndSelect
EndIf

If $iSort Then ; Save in relevant folders for later sorting

If $fFolder Then
If StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then
_RFLTA_AddToList($asFolderMatchList, $sRetPath & $sName & $sFolderSlash)
EndIf
Else
If StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then
; Select required list for files
If $sCurrentPath = $sInitialPath Then
_RFLTA_AddToList($asRootFileMatchList, $sRetPath & $sName)
Else
_RFLTA_AddToList($asFileMatchList, $sRetPath & $sName)
EndIf
EndIf
EndIf

Else ; Save directly in return list
If $fFolder Then
If $iReturn <> 1 And StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then
_RFLTA_AddToList($asReturnList, $sRetPath & $sName & $sFolderSlash)
EndIf
Else
If $iReturn <> 2 And StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then
_RFLTA_AddToList($asReturnList, $sRetPath & $sName)
EndIf
EndIf
EndIf

WEnd

; Close current search
FileClose($hSearch)
WEnd

If $iSort Then

; Check if any file/folders have been added depending on required return
Switch $iReturn
Case 0 ; If no folders then number of files is immaterial
If $asRootFileMatchList[0] = 0 And $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "")
Case 1
If $asRootFileMatchList[0] = 0 And $asFileMatchList[0] = 0 Then Return SetError(1, 9, "")
Case 2
If $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "")
EndSwitch

Switch $iReturn
Case 2 ; Folders only
; Correctly size folder match list
ReDim $asFolderMatchList[$asFolderMatchList[0] + 1]
; Copy size folder match array
$asReturnList = $asFolderMatchList
; Simple sort list
_RFLTA_ArraySort($asReturnList)
Case 1 ; Files only
If $iReturnPath = 0 Then ; names only so simple sort suffices
; Combine file match lists
_RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList)
; Simple sort combined file list
_RFLTA_ArraySort($asReturnList)
Else
; Combine sorted file match lists
_RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList, 1)
EndIf
Case 0 ; Both files and folders
If $iReturnPath = 0 Then ; names only so simple sort suffices
; Combine file match lists
_RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList)
; Set correct count for folder add
$asReturnList[0] += $asFolderMatchList[0]
; Resize and add file match array
ReDim $asFolderMatchList[$asFolderMatchList[0] + 1]
_RFLTA_ArrayConcatenate($asReturnList, $asFolderMatchList)
; Simple sort final list
_RFLTA_ArraySort($asReturnList)
Else
; Size return list
Local $asReturnList[$asFileMatchList[0] + $asRootFileMatchList[0] + $asFolderMatchList[0] + 1]
$asReturnList[0] = $asFileMatchList[0] + $asRootFileMatchList[0] + $asFolderMatchList[0]
; Sort root file list
_RFLTA_ArraySort($asRootFileMatchList, 1, $asRootFileMatchList[0])
; Add the sorted root files at the top
For $i = 1 To $asRootFileMatchList[0]
$asReturnList[$i] = $asRootFileMatchList[$i]
Next
; Set next insertion index
Local $iNextInsertionIndex = $asRootFileMatchList[0] + 1
; Sort folder list
_RFLTA_ArraySort($asFolderMatchList, 1, $asFolderMatchList[0])
; Work through folder list
For $i = 1 To $asFolderMatchList[0]
; Format folder name for search
If $sFolderSlash Then
$sFolderToFind = $asFolderMatchList[$i]
Else
$sFolderToFind = $asFolderMatchList[$i] & "\"
EndIf
; Find folder in FolderFileSectionList
For $j = 1 To $asFolderFileSectionList[0][0]
If $sFolderToFind = $asFolderFileSectionList[$j][0] Then ExitLoop
Next
; Set file list indexes
$iFileSectionStartIndex = $asFolderFileSectionList[$j][1]
If $j = $asFolderFileSectionList[0][0] Then
$iFileSectionEndIndex = $asFileMatchList[0]
Else
$iFileSectionEndIndex = $asFolderFileSectionList[$j + 1][1] - 1
EndIf
; Sort files if required
If $iSort = 1 Then
_RFLTA_ArraySort($asFileMatchList, $iFileSectionStartIndex, $iFileSectionEndIndex)
EndIf
; Add folder to return list
$asReturnList[$iNextInsertionIndex] = $asFolderMatchList[$i]
$iNextInsertionIndex += 1
; Add files to return list
For $j = $iFileSectionStartIndex To $iFileSectionEndIndex
$asReturnList[$iNextInsertionIndex] = $asFileMatchList[$j]
$iNextInsertionIndex += 1
Next
Next
EndIf
EndSwitch

Else ; No sort

; Check if any file/folders have been added
If $asReturnList[0] = 0 Then Return SetError(1, 9, "")

; Remove any unused return list elements from last ReDim
ReDim $asReturnList[$asReturnList[0] + 1]

EndIf

Return $asReturnList
EndFunc   ;==>_RecFileListToArray

Now the function have 2 new value: $sTotal_File And $sProgress. In the first you have to inserct the total file present in the directory/drive in the second value you have to

I've added this new function:

Func _RFLTA_Progress($vProgress = "",$sTotal = 0)
$sCurrent_File = $sCurrent_File + 1
Return GUICtrlSetData($vProgress,$sCurrent_File *100/$sTotal)
EndFunc

This is a sample code :

#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <Array.au3>
$hGUI = GUICreate("Test", 500, 500)
$Progress1 = GUICtrlCreateProgress(10, 10, 400, 20)
GUISetState()
$Dir_Info = DirGetSize("C:\", 1)
$File_Number = $Dir_Info[1]
$Search_File = _RecFileListToArray("C:\", "*.tmp", 1, 1, 0, 2, "", "", $File_Number, $Progress1)
If IsArray($Search_File) Then
MsgBox (0,"Done","Item found!")
_ArrayDisplay($Search_File)
EndIf
While 1
Switch GUIGetMsg()
  Case $GUI_EVENT_CLOSE
   Exit
EndSwitch
WEnd

Func _RecFileListToArray($sInitialPath, $sInclude_List = "*", $iReturn = 0, $iRecur = 0, $iSort = 0, $iReturnPath = 1, $sExclude_List = "", $sExclude_List_Folder = "", $sTotal_File = 0, $sProgress = "")
Local $asReturnList[100] = [0], $asFileMatchList[100] = [0], $asRootFileMatchList[100] = [0], $asFolderMatchList[100] = [0], $asFolderSearchList[100] = [1]
Local $sFolderSlash = "", $iMaxLevel, $sInclude_File_Mask, $sExclude_File_Mask, $sInclude_Folder_Mask = ".+", $sExclude_Folder_Mask = ":"
Local $hSearch, $fFolder, $sRetPath = "", $sCurrentPath, $sName
Local $asFolderFileSectionList[100][2] = [[0, 0]], $sFolderToFind, $iFileSectionStartIndex, $iFileSectionEndIndex
Global $sCurrent_File = 0
; Check for valid path
If Not FileExists($sInitialPath) Then Return SetError(1, 1, "")
; Check if folders should have trailing \ and ensure that initial path does have one
If StringRight($sInitialPath, 1) = "\" Then
  $sFolderSlash = "\"
Else
  $sInitialPath = $sInitialPath & "\"
EndIf
; Add path to folder search list
$asFolderSearchList[1] = $sInitialPath
; Check for valid recur value
If $iRecur > 1 Or Not IsInt($iRecur) Then Return SetError(1, 4, "")
; If required, determine \ count for max recursive level setting
If $iRecur < 0 Then
  StringReplace($sInitialPath, "\", "", 2)
  $iMaxLevel = @extended - $iRecur
EndIf
; Create Include mask for files
If $sInclude_List = "*" Then
  $sInclude_File_Mask = ".+"
Else
  If Not _RFLTA_ListToMask($sInclude_File_Mask, $sInclude_List) Then Return SetError(1, 2, "")
EndIf
; Set Include mask for folders
Switch $iReturn
  Case 0
   ; Folders affected by mask if not recursive
   Switch $iRecur
    Case 0
     ; Folders match mask for compatibility
     $sInclude_Folder_Mask = $sInclude_File_Mask
     ;Case Else
     ; All folders match
   EndSwitch
   ;Case 1
   ; All folders match
  Case 2
   ; Folders affected by mask
   $sInclude_Folder_Mask = $sInclude_File_Mask
EndSwitch
; Create Exclude List mask for files
If $sExclude_List = "" Then
  $sExclude_File_Mask = ":" ; Set unmatchable mask
Else
  If Not _RFLTA_ListToMask($sExclude_File_Mask, $sExclude_List) Then Return SetError(1, 7, "")
EndIf
; Set Exclude mask for folders
Switch $iReturn
  Case 0
   ; Folders affected by mask if not recursive
   Switch $iRecur
    Case 0
     ; Folders match mask for compatibility
     $sExclude_Folder_Mask = $sExclude_File_Mask
    Case Else
     ; Exclude defined folders as set in extended
     If $sExclude_List_Folder <> "" Then
      If Not _RFLTA_ListToMask($sExclude_Folder_Mask, $sExclude_List_Folder) Then Return SetError(1, 8, "")
     EndIf
   EndSwitch
   ;Case 1
   ; All folders match
  Case 2
   ; Folders affected by normal mask
   $sExclude_Folder_Mask = $sExclude_File_Mask
EndSwitch
; Verify other parameters
If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(1, 3, "")
If Not ($iSort = 0 Or $iSort = 1 Or $iSort = 2) Then Return SetError(1, 5, "")
If Not ($iReturnPath = 0 Or $iReturnPath = 1 Or $iReturnPath = 2) Then Return SetError(1, 6, "")
; Search within listed folders
While $asFolderSearchList[0] > 0
  ; Set path to search
  $sCurrentPath = $asFolderSearchList[$asFolderSearchList[0]]
  ; Reduce folder search list count
  $asFolderSearchList[0] -= 1
  ; Determine return path to add to file/folder name
  Switch $iReturnPath
   ; Case 0 ; Name only
   ; Leave as ""
   Case 1 ;Relative to initial path
    $sRetPath = StringReplace($sCurrentPath, $sInitialPath, "")
   Case 2 ; Full path
    $sRetPath = $sCurrentPath
  EndSwitch
  ; Get search handle
  $hSearch = FileFindFirstFile($sCurrentPath & "*")
  ; If sorting files and folders with paths then store folder name and position of associated files in list
  If $iReturn = 0 And $iSort And $iReturnPath Then
   _RFLTA_AddToList($asFolderFileSectionList, $sRetPath, $asFileMatchList[0] + 1)
  EndIf
  ; If folder empty move to next in list
  If $hSearch = -1 Then
   ContinueLoop
  EndIf
  ; Search folder
  While 1
   If $sTotal_File > 0 And $sProgress <> "" Then _RFLTA_Progress($sProgress, $sTotal_File)
   $sName = FileFindNextFile($hSearch)
   ; Check for end of folder
   If @error Then
    ExitLoop
   EndIf
   ;
   ; Set subfolder flag - @extended set in 3.3.1.1 +
   $fFolder = @extended
   ; If folder then check whether to add to search list
   If $fFolder Then
    Select
     Case $iRecur < 0 ; Check recur depth
      StringReplace($sCurrentPath, "\", "", 0, 2)
      If @extended < $iMaxLevel Then
       ContinueCase ; Check if matched to masks
      EndIf
     Case $iRecur = 1 ; Full recur
      If Not StringRegExp($sName, $sExclude_Folder_Mask) Then ; Add folder unless excluded
       _RFLTA_AddToList($asFolderSearchList, $sCurrentPath & $sName & "\")
      EndIf
      ; Case $iRecur = 0 ; Never add
      ; Do nothing
    EndSelect
   EndIf
   If $iSort Then ; Save in relevant folders for later sorting
    If $fFolder Then
     If StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then
      _RFLTA_AddToList($asFolderMatchList, $sRetPath & $sName & $sFolderSlash)
     EndIf
    Else
     If StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then
      ; Select required list for files
      If $sCurrentPath = $sInitialPath Then
       _RFLTA_AddToList($asRootFileMatchList, $sRetPath & $sName)
      Else
       _RFLTA_AddToList($asFileMatchList, $sRetPath & $sName)
      EndIf
     EndIf
    EndIf
   Else ; Save directly in return list
    If $fFolder Then
     If $iReturn <> 1 And StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then
      _RFLTA_AddToList($asReturnList, $sRetPath & $sName & $sFolderSlash)
     EndIf
    Else
     If $iReturn <> 2 And StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then
      _RFLTA_AddToList($asReturnList, $sRetPath & $sName)
     EndIf
    EndIf
   EndIf
  WEnd
  ; Close current search
  FileClose($hSearch)
WEnd
If $iSort Then
  ; Check if any file/folders have been added depending on required return
  Switch $iReturn
   Case 0 ; If no folders then number of files is immaterial
    If $asRootFileMatchList[0] = 0 And $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "")
   Case 1
    If $asRootFileMatchList[0] = 0 And $asFileMatchList[0] = 0 Then Return SetError(1, 9, "")
   Case 2
    If $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "")
  EndSwitch
  Switch $iReturn
   Case 2 ; Folders only
    ; Correctly size folder match list
    ReDim $asFolderMatchList[$asFolderMatchList[0] + 1]
    ; Copy size folder match array
    $asReturnList = $asFolderMatchList
    ; Simple sort list
    _RFLTA_ArraySort($asReturnList)
   Case 1 ; Files only
    If $iReturnPath = 0 Then ; names only so simple sort suffices
     ; Combine file match lists
     _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList)
     ; Simple sort combined file list
     _RFLTA_ArraySort($asReturnList)
    Else
     ; Combine sorted file match lists
     _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList, 1)
    EndIf
   Case 0 ; Both files and folders
    If $iReturnPath = 0 Then ; names only so simple sort suffices
     ; Combine file match lists
     _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList)
     ; Set correct count for folder add
     $asReturnList[0] += $asFolderMatchList[0]
     ; Resize and add file match array
     ReDim $asFolderMatchList[$asFolderMatchList[0] + 1]
     _RFLTA_ArrayConcatenate($asReturnList, $asFolderMatchList)
     ; Simple sort final list
     _RFLTA_ArraySort($asReturnList)
    Else
     ; Size return list
     Local $asReturnList[$asFileMatchList[0] + $asRootFileMatchList[0] + $asFolderMatchList[0] + 1]
     $asReturnList[0] = $asFileMatchList[0] + $asRootFileMatchList[0] + $asFolderMatchList[0]
     ; Sort root file list
     _RFLTA_ArraySort($asRootFileMatchList, 1, $asRootFileMatchList[0])
     ; Add the sorted root files at the top
     For $i = 1 To $asRootFileMatchList[0]
      $asReturnList[$i] = $asRootFileMatchList[$i]
     Next
     ; Set next insertion index
     Local $iNextInsertionIndex = $asRootFileMatchList[0] + 1
     ; Sort folder list
     _RFLTA_ArraySort($asFolderMatchList, 1, $asFolderMatchList[0])
     ; Work through folder list
     For $i = 1 To $asFolderMatchList[0]
      ; Format folder name for search
      If $sFolderSlash Then
       $sFolderToFind = $asFolderMatchList[$i]
      Else
       $sFolderToFind = $asFolderMatchList[$i] & "\"
      EndIf
      ; Find folder in FolderFileSectionList
      For $j = 1 To $asFolderFileSectionList[0][0]
       If $sFolderToFind = $asFolderFileSectionList[$j][0] Then ExitLoop
      Next
      ; Set file list indexes
      $iFileSectionStartIndex = $asFolderFileSectionList[$j][1]
      If $j = $asFolderFileSectionList[0][0] Then
       $iFileSectionEndIndex = $asFileMatchList[0]
      Else
       $iFileSectionEndIndex = $asFolderFileSectionList[$j + 1][1] - 1
      EndIf
      ; Sort files if required
      If $iSort = 1 Then
       _RFLTA_ArraySort($asFileMatchList, $iFileSectionStartIndex, $iFileSectionEndIndex)
      EndIf
      ; Add folder to return list
      $asReturnList[$iNextInsertionIndex] = $asFolderMatchList[$i]
      $iNextInsertionIndex += 1
      ; Add files to return list
      For $j = $iFileSectionStartIndex To $iFileSectionEndIndex
       $asReturnList[$iNextInsertionIndex] = $asFileMatchList[$j]
       $iNextInsertionIndex += 1
      Next
     Next
    EndIf
  EndSwitch
Else ; No sort
  ; Check if any file/folders have been added
  If $asReturnList[0] = 0 Then Return SetError(1, 9, "")
  ; Remove any unused return list elements from last ReDim
  ReDim $asReturnList[$asReturnList[0] + 1]
EndIf
Return $asReturnList

EndFunc   ;==>_RecFileListToArray
Func _RFLTA_ListToMask(ByRef $sMask, $sList)
; Check for invalid characters within list
If StringRegExp($sList, "\\|/|:|\<|\>|\|") Then Return 0
; Strip WS and insert | for ;
$sList = StringReplace(StringStripWS(StringRegExpReplace($sList, "\s*;\s*", ";"), 3), ";", "|")
; Convert to SRE pattern
$sList = StringReplace(StringReplace(StringRegExpReplace($sList, "[][$^.{}()+\-]", "\\$0"), "?", "."), "*", ".*?")
; Add prefix and suffix
$sMask = "(?i)^(" & $sList & ")\z"
Return 1
EndFunc   ;==>_RFLTA_ListToMask
Func _RFLTA_AddToList(ByRef $aList, $vValue_0, $vValue_1 = -1)
If $vValue_1 = -1 Then ; [?] array
  ; Increase list count
  $aList[0] += 1
  ; Double list size if too small (fewer ReDim needed)
  If UBound($aList) <= $aList[0] Then ReDim $aList[UBound($aList) * 2]
  ; Add value
  $aList[$aList[0]] = $vValue_0
Else ; [?][2] array
  $aList[0][0] += 1
  If UBound($aList) <= $aList[0][0] Then ReDim $aList[UBound($aList) * 2][2]
  $aList[$aList[0][0]][0] = $vValue_0
  $aList[$aList[0][0]][1] = $vValue_1
EndIf
EndFunc   ;==>_RFLTA_AddToList
Func _RFLTA_AddFileLists(ByRef $asTarget, $asSource_1, $asSource_2, $iSort = 0)
; Correctly size root file match array
ReDim $asSource_1[$asSource_1[0] + 1]
; Simple sort root file match array if required
If $iSort = 1 Then _RFLTA_ArraySort($asSource_1)
; Copy root file match array
$asTarget = $asSource_1
; Add file match count
$asTarget[0] += $asSource_2[0]
; Correctly size file match array
ReDim $asSource_2[$asSource_2[0] + 1]
; Simple sort file match array if required
If $iSort = 1 Then _RFLTA_ArraySort($asSource_2)
; Add file match array
_RFLTA_ArrayConcatenate($asTarget, $asSource_2)
EndFunc   ;==>_RFLTA_AddFileLists
Func _RFLTA_FileListSearch(Const ByRef $avArray, $vValue, $iIndex, $sSlash)
Local $aRet[2]
; Add final \ if required
If Not $sSlash Then $vValue &= "\"
; Start by getting top match - search down from start index
For $i = $iIndex To $avArray[0]
  ; SRE gives path less filename
  If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") = $vValue Then ExitLoop
Next
If $i > $avArray[0] Then
  ; No match found so look from start index upwards
  If $iIndex = $avArray[0] Then $iIndex -= 1
  For $i = $iIndex + 1 To 1 Step -1
   If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") = $vValue Then ExitLoop
  Next
  ; If still no match - return " nothing found" for empty folder
  If $i = 0 Then Return SetError(1, 0, "")
  ; Set index of bottom file
  $aRet[1] = $i
  ; Now look for top match
  For $i = $aRet[1] To 1 Step -1
   If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") <> $vValue Then ExitLoop
  Next
  ; Set top match
  $aRet[0] = $i + 1
Else
  ; Set index of top associated file
  $aRet[0] = $i
  ; Now look for bottom match - find first file which does not match
  For $i = $aRet[0] To $avArray[0]
   If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") <> $vValue Then ExitLoop
  Next
  ; Set bottom match
  $aRet[1] = $i - 1
EndIf
Return $aRet
EndFunc   ;==>_RFLTA_FileListSearch
Func _RFLTA_ArraySort(ByRef $avArray, $iStart = 1, $iEnd = -99)
If $iEnd = -99 Then $iEnd = UBound($avArray) - 1
_RFLTA_QuickSort($avArray, $iStart, $iEnd)
EndFunc   ;==>_RFLTA_ArraySort
Func _RFLTA_QuickSort(ByRef $avArray, ByRef $iStart, ByRef $iEnd)
Local $vTmp
If ($iEnd - $iStart) < 15 Then
  Local $i, $j, $vCur
  For $i = $iStart + 1 To $iEnd
   $vTmp = $avArray[$i]
   If IsNumber($vTmp) Then
    For $j = $i - 1 To $iStart Step -1
     $vCur = $avArray[$j]
     If ($vTmp >= $vCur And IsNumber($vCur)) Or (Not IsNumber($vCur) And StringCompare($vTmp, $vCur) >= 0) Then ExitLoop
     $avArray[$j + 1] = $vCur
    Next
   Else
    For $j = $i - 1 To $iStart Step -1
     If (StringCompare($vTmp, $avArray[$j]) >= 0) Then ExitLoop
     $avArray[$j + 1] = $avArray[$j]
    Next
   EndIf
   $avArray[$j + 1] = $vTmp
  Next
  Return
EndIf
Local $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)], $fNum = IsNumber($vPivot)
Do
  If $fNum Then
   While ($avArray[$L] < $vPivot And IsNumber($avArray[$L])) Or (Not IsNumber($avArray[$L]) And StringCompare($avArray[$L], $vPivot) < 0)
    $L += 1
   WEnd
   While ($avArray[$R] > $vPivot And IsNumber($avArray[$R])) Or (Not IsNumber($avArray[$R]) And StringCompare($avArray[$R], $vPivot) > 0)
    $R -= 1
   WEnd
  Else
   While (StringCompare($avArray[$L], $vPivot) < 0)
    $L += 1
   WEnd
   While (StringCompare($avArray[$R], $vPivot) > 0)
    $R -= 1
   WEnd
  EndIf
  If $L <= $R Then
   $vTmp = $avArray[$L]
   $avArray[$L] = $avArray[$R]
   $avArray[$R] = $vTmp
   $L += 1
   $R -= 1
  EndIf
Until $L > $R
_RFLTA_QuickSort($avArray, $iStart, $R)
_RFLTA_QuickSort($avArray, $L, $iEnd)
EndFunc   ;==>_RFLTA_QuickSort
Func _RFLTA_ArrayConcatenate(ByRef $avArrayTarget, Const ByRef $avArraySource)
Local $iUBoundTarget = UBound($avArrayTarget) - 1, $iUBoundSource = UBound($avArraySource)
ReDim $avArrayTarget[$iUBoundTarget + $iUBoundSource]
For $i = 1 To $iUBoundSource - 1
  $avArrayTarget[$iUBoundTarget + $i] = $avArraySource[$i]
Next
EndFunc   ;==>_RFLTA_ArrayConcatenate
Func _RFLTA_Progress($vProgress = "", $sTotal = 0)
$sCurrent_File = $sCurrent_File + 1
Return GUICtrlSetData($vProgress, $sCurrent_File * 100 / $sTotal)
EndFunc   ;==>_RFLTA_Progress

The only problem is that DirGetSize() is too slow at first run when it have to count the total file in a directory/drive. Do you know a soluction to speed up that?

Another question, do you think is possible to be stoopable the _RecFileListToArray(), for example if an user see that the process can take too much time it can simply "cancel" the search process. Is possible?

Hi :oops:

Link to comment
Share on other sites

  • Moderators

StungStang,

Please feel free to amend the code as you want - but remember you then have to support it! :doh:

The only problem is that DirGetSize() is too slow at first run when it have to count the total file in a directory/drive. Do you know a soluction to speed up that?

That is the very problem I mentioned above - you need 2 searches to make the progress bar work- very inefficient and slow. :bye:

do you think is possible to be stoopable the _RecFileListToArray

Absolutely, there are many loops and so the function can be interrupted easily. Take a look at the Interrupting a running function tutorial in the Wiki - that shows you several ways to do it. Please ask again if you run into difficulty integrating code form the tutorial into the function. :oops:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I don't know if i have do it done this is my code now:

#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <Array.au3>
Local $BreaK = 0
$hGUI = GUICreate("Test", 500, 500)
$Progress1 = GUICtrlCreateProgress(10, 10, 400, 20)
$StopIT = GUICtrlCreateButton("Search", 72, 136, 363, 73)
GUISetState(@SW_SHOW)
$Dir_Info = DirGetSize("C:", 1)
$File_Number = $Dir_Info[1]
While 1
Switch GUIGetMsg()
  Case $GUI_EVENT_CLOSE
   Exit
  Case $StopIT
   If GUICtrlRead($StopIT) == "Search" Then
    GUICtrlSetData($StopIT, "Cancel")
    Opt("GUIOnEventMode", 1)
    GUICtrlSetOnEvent($StopIT, "_Break")
    $Search_File = _RecFileListToArray("C:", "*.tmp", 1, 1, 0, 2, "", "", $File_Number, $Progress1)
    If $BreaK = 0 Then
     Opt("GUIOnEventMode",0)
     If IsArray($Search_File) Then
      MsgBox(0, "Done", "Item found!")
      _ArrayDisplay($Search_File)
     EndIf
    Else
     $BreaK = 0
     Opt("GUIOnEventMode",0)
     MsgBox(0, "OK", "You have cancelled the search :(")
    EndIf
    GUICtrlSetData($StopIT, "Search")
   Else
    $File_Searching = False
    GUICtrlSetData($StopIT, "Search")
   EndIf

EndSwitch
WEnd
Func _Break()
$BreaK = 1
EndFunc   ;==>_Break
Func _RecFileListToArray($sInitialPath, $sInclude_List = "*", $iReturn = 0, $iRecur = 0, $iSort = 0, $iReturnPath = 1, $sExclude_List = "", $sExclude_List_Folder = "", $sTotal_File = 0, $sProgress = "")
Local $asReturnList[100] = [0], $asFileMatchList[100] = [0], $asRootFileMatchList[100] = [0], $asFolderMatchList[100] = [0], $asFolderSearchList[100] = [1]
Local $sFolderSlash = "", $iMaxLevel, $sInclude_File_Mask, $sExclude_File_Mask, $sInclude_Folder_Mask = ".+", $sExclude_Folder_Mask = ":"
Local $hSearch, $fFolder, $sRetPath = "", $sCurrentPath, $sName
Local $asFolderFileSectionList[100][2] = [[0, 0]], $sFolderToFind, $iFileSectionStartIndex, $iFileSectionEndIndex
Global $sCurrent_File = 0
; Check for valid path
If Not FileExists($sInitialPath) Then Return SetError(1, 1, "")
; Check if folders should have trailing  and ensure that initial path does have one
If StringRight($sInitialPath, 1) = "" Then
  $sFolderSlash = ""
Else
  $sInitialPath = $sInitialPath & ""
EndIf
; Add path to folder search list
$asFolderSearchList[1] = $sInitialPath
; Check for valid recur value
If $iRecur > 1 Or Not IsInt($iRecur) Then Return SetError(1, 4, "")
; If required, determine  count for max recursive level setting
If $iRecur < 0 Then
  StringReplace($sInitialPath, "", "", 2)
  $iMaxLevel = @extended - $iRecur
EndIf
; Create Include mask for files
If $sInclude_List = "*" Then
  $sInclude_File_Mask = ".+"
Else
  If Not _RFLTA_ListToMask($sInclude_File_Mask, $sInclude_List) Then Return SetError(1, 2, "")
EndIf
; Set Include mask for folders
Switch $iReturn
  Case 0
   ; Folders affected by mask if not recursive
   Switch $iRecur
    Case 0
     ; Folders match mask for compatibility
     $sInclude_Folder_Mask = $sInclude_File_Mask
     ;Case Else
     ; All folders match
   EndSwitch
   ;Case 1
   ; All folders match
  Case 2
   ; Folders affected by mask
   $sInclude_Folder_Mask = $sInclude_File_Mask
EndSwitch
; Create Exclude List mask for files
If $sExclude_List = "" Then
  $sExclude_File_Mask = ":" ; Set unmatchable mask
Else
  If Not _RFLTA_ListToMask($sExclude_File_Mask, $sExclude_List) Then Return SetError(1, 7, "")
EndIf
; Set Exclude mask for folders
Switch $iReturn
  Case 0
   ; Folders affected by mask if not recursive
   Switch $iRecur
    Case 0
     ; Folders match mask for compatibility
     $sExclude_Folder_Mask = $sExclude_File_Mask
    Case Else
     ; Exclude defined folders as set in extended
     If $sExclude_List_Folder <> "" Then
      If Not _RFLTA_ListToMask($sExclude_Folder_Mask, $sExclude_List_Folder) Then Return SetError(1, 8, "")
     EndIf
   EndSwitch
   ;Case 1
   ; All folders match
  Case 2
   ; Folders affected by normal mask
   $sExclude_Folder_Mask = $sExclude_File_Mask
EndSwitch
; Verify other parameters
If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(1, 3, "")
If Not ($iSort = 0 Or $iSort = 1 Or $iSort = 2) Then Return SetError(1, 5, "")
If Not ($iReturnPath = 0 Or $iReturnPath = 1 Or $iReturnPath = 2) Then Return SetError(1, 6, "")
; Search within listed folders
While $asFolderSearchList[0] > 0
  If $BreaK = 1 Then
   ConsoleWrite("Stopped") ;Debug purpose only
   If $sProgress <> "" Then GUICtrlSetData($sProgress, 0) ;Reset the progress bar
   ExitLoop
   Return
  EndIf
  ; Set path to search
  $sCurrentPath = $asFolderSearchList[$asFolderSearchList[0]]
  ; Reduce folder search list count
  $asFolderSearchList[0] -= 1
  ; Determine return path to add to file/folder name
  Switch $iReturnPath
   ; Case 0 ; Name only
   ; Leave as ""
   Case 1 ;Relative to initial path
    $sRetPath = StringReplace($sCurrentPath, $sInitialPath, "")
   Case 2 ; Full path
    $sRetPath = $sCurrentPath
  EndSwitch
  ; Get search handle
  $hSearch = FileFindFirstFile($sCurrentPath & "*")
  ; If sorting files and folders with paths then store folder name and position of associated files in list
  If $iReturn = 0 And $iSort And $iReturnPath Then
   _RFLTA_AddToList($asFolderFileSectionList, $sRetPath, $asFileMatchList[0] + 1)
  EndIf
  ; If folder empty move to next in list
  If $hSearch = -1 Then
   ContinueLoop
  EndIf
  ; Search folder
  While 1
   If $sTotal_File > 0 And $sProgress <> "" Then _RFLTA_Progress($sProgress, $sTotal_File)
   $sName = FileFindNextFile($hSearch)
   ; Check for end of folder
   If @error Then
    ExitLoop
   EndIf
   ;
   ; Set subfolder flag - @extended set in 3.3.1.1 +
   $fFolder = @extended
   ; If folder then check whether to add to search list
   If $fFolder Then
    Select
     Case $iRecur < 0 ; Check recur depth
      StringReplace($sCurrentPath, "", "", 0, 2)
      If @extended < $iMaxLevel Then
       ContinueCase ; Check if matched to masks
      EndIf
     Case $iRecur = 1 ; Full recur
      If Not StringRegExp($sName, $sExclude_Folder_Mask) Then ; Add folder unless excluded
       _RFLTA_AddToList($asFolderSearchList, $sCurrentPath & $sName & "")
      EndIf
      ; Case $iRecur = 0 ; Never add
      ; Do nothing
    EndSelect
   EndIf
   If $iSort Then ; Save in relevant folders for later sorting
    If $fFolder Then
     If StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then
      _RFLTA_AddToList($asFolderMatchList, $sRetPath & $sName & $sFolderSlash)
     EndIf
    Else
     If StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then
      ; Select required list for files
      If $sCurrentPath = $sInitialPath Then
       _RFLTA_AddToList($asRootFileMatchList, $sRetPath & $sName)
      Else
       _RFLTA_AddToList($asFileMatchList, $sRetPath & $sName)
      EndIf
     EndIf
    EndIf
   Else ; Save directly in return list
    If $fFolder Then
     If $iReturn <> 1 And StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then
      _RFLTA_AddToList($asReturnList, $sRetPath & $sName & $sFolderSlash)
     EndIf
    Else
     If $iReturn <> 2 And StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then
      _RFLTA_AddToList($asReturnList, $sRetPath & $sName)
     EndIf
    EndIf
   EndIf
  WEnd
  ; Close current search
  FileClose($hSearch)
WEnd
If $iSort Then
  ; Check if any file/folders have been added depending on required return
  Switch $iReturn
   Case 0 ; If no folders then number of files is immaterial
    If $asRootFileMatchList[0] = 0 And $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "")
   Case 1
    If $asRootFileMatchList[0] = 0 And $asFileMatchList[0] = 0 Then Return SetError(1, 9, "")
   Case 2
    If $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "")
  EndSwitch
  Switch $iReturn
   Case 2 ; Folders only
    ; Correctly size folder match list
    ReDim $asFolderMatchList[$asFolderMatchList[0] + 1]
    ; Copy size folder match array
    $asReturnList = $asFolderMatchList
    ; Simple sort list
    _RFLTA_ArraySort($asReturnList)
   Case 1 ; Files only
    If $iReturnPath = 0 Then ; names only so simple sort suffices
     ; Combine file match lists
     _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList)
     ; Simple sort combined file list
     _RFLTA_ArraySort($asReturnList)
    Else
     ; Combine sorted file match lists
     _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList, 1)
    EndIf
   Case 0 ; Both files and folders
    If $iReturnPath = 0 Then ; names only so simple sort suffices
     ; Combine file match lists
     _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList)
     ; Set correct count for folder add
     $asReturnList[0] += $asFolderMatchList[0]
     ; Resize and add file match array
     ReDim $asFolderMatchList[$asFolderMatchList[0] + 1]
     _RFLTA_ArrayConcatenate($asReturnList, $asFolderMatchList)
     ; Simple sort final list
     _RFLTA_ArraySort($asReturnList)
    Else
     ; Size return list
     Local $asReturnList[$asFileMatchList[0] + $asRootFileMatchList[0] + $asFolderMatchList[0] + 1]
     $asReturnList[0] = $asFileMatchList[0] + $asRootFileMatchList[0] + $asFolderMatchList[0]
     ; Sort root file list
     _RFLTA_ArraySort($asRootFileMatchList, 1, $asRootFileMatchList[0])
     ; Add the sorted root files at the top
     For $i = 1 To $asRootFileMatchList[0]
      $asReturnList[$i] = $asRootFileMatchList[$i]
     Next
     ; Set next insertion index
     Local $iNextInsertionIndex = $asRootFileMatchList[0] + 1
     ; Sort folder list
     _RFLTA_ArraySort($asFolderMatchList, 1, $asFolderMatchList[0])
     ; Work through folder list
     For $i = 1 To $asFolderMatchList[0]
      ; Format folder name for search
      If $sFolderSlash Then
       $sFolderToFind = $asFolderMatchList[$i]
      Else
       $sFolderToFind = $asFolderMatchList[$i] & ""
      EndIf
      ; Find folder in FolderFileSectionList
      For $j = 1 To $asFolderFileSectionList[0][0]
       If $sFolderToFind = $asFolderFileSectionList[$j][0] Then ExitLoop
      Next
      ; Set file list indexes
      $iFileSectionStartIndex = $asFolderFileSectionList[$j][1]
      If $j = $asFolderFileSectionList[0][0] Then
       $iFileSectionEndIndex = $asFileMatchList[0]
      Else
       $iFileSectionEndIndex = $asFolderFileSectionList[$j + 1][1] - 1
      EndIf
      ; Sort files if required
      If $iSort = 1 Then
       _RFLTA_ArraySort($asFileMatchList, $iFileSectionStartIndex, $iFileSectionEndIndex)
      EndIf
      ; Add folder to return list
      $asReturnList[$iNextInsertionIndex] = $asFolderMatchList[$i]
      $iNextInsertionIndex += 1
      ; Add files to return list
      For $j = $iFileSectionStartIndex To $iFileSectionEndIndex
       $asReturnList[$iNextInsertionIndex] = $asFileMatchList[$j]
       $iNextInsertionIndex += 1
      Next
     Next
    EndIf
  EndSwitch
Else ; No sort
  ; Check if any file/folders have been added
  If $asReturnList[0] = 0 Then Return SetError(1, 9, "")
  ; Remove any unused return list elements from last ReDim
  ReDim $asReturnList[$asReturnList[0] + 1]
EndIf
Return $asReturnList
EndFunc   ;==>_RecFileListToArray
Func _RFLTA_ListToMask(ByRef $sMask, $sList)
; Check for invalid characters within list
If StringRegExp($sList, "|/|:|<|>||") Then Return 0
; Strip WS and insert | for ;
$sList = StringReplace(StringStripWS(StringRegExpReplace($sList, "s*;s*", ";"), 3), ";", "|")
; Convert to SRE pattern
$sList = StringReplace(StringReplace(StringRegExpReplace($sList, "[][$^.{}()+-]", "$0"), "?", "."), "*", ".*?")
; Add prefix and suffix
$sMask = "(?i)^(" & $sList & ")z"
Return 1
EndFunc   ;==>_RFLTA_ListToMask
Func _RFLTA_AddToList(ByRef $aList, $vValue_0, $vValue_1 = -1)
If $vValue_1 = -1 Then ; [?] array
  ; Increase list count
  $aList[0] += 1
  ; Double list size if too small (fewer ReDim needed)
  If UBound($aList) <= $aList[0] Then ReDim $aList[UBound($aList) * 2]
  ; Add value
  $aList[$aList[0]] = $vValue_0
Else ; [?][2] array
  $aList[0][0] += 1
  If UBound($aList) <= $aList[0][0] Then ReDim $aList[UBound($aList) * 2][2]
  $aList[$aList[0][0]][0] = $vValue_0
  $aList[$aList[0][0]][1] = $vValue_1
EndIf
EndFunc   ;==>_RFLTA_AddToList
Func _RFLTA_AddFileLists(ByRef $asTarget, $asSource_1, $asSource_2, $iSort = 0)
; Correctly size root file match array
ReDim $asSource_1[$asSource_1[0] + 1]
; Simple sort root file match array if required
If $iSort = 1 Then _RFLTA_ArraySort($asSource_1)
; Copy root file match array
$asTarget = $asSource_1
; Add file match count
$asTarget[0] += $asSource_2[0]
; Correctly size file match array
ReDim $asSource_2[$asSource_2[0] + 1]
; Simple sort file match array if required
If $iSort = 1 Then _RFLTA_ArraySort($asSource_2)
; Add file match array
_RFLTA_ArrayConcatenate($asTarget, $asSource_2)
EndFunc   ;==>_RFLTA_AddFileLists
Func _RFLTA_FileListSearch(Const ByRef $avArray, $vValue, $iIndex, $sSlash)
Local $aRet[2]
; Add final  if required
If Not $sSlash Then $vValue &= ""
; Start by getting top match - search down from start index
For $i = $iIndex To $avArray[0]
  ; SRE gives path less filename
  If StringRegExpReplace($avArray[$i], "(^.*)(.*)", "1") = $vValue Then ExitLoop
Next
If $i > $avArray[0] Then
  ; No match found so look from start index upwards
  If $iIndex = $avArray[0] Then $iIndex -= 1
  For $i = $iIndex + 1 To 1 Step -1
   If StringRegExpReplace($avArray[$i], "(^.*)(.*)", "1") = $vValue Then ExitLoop
  Next
  ; If still no match - return " nothing found" for empty folder
  If $i = 0 Then Return SetError(1, 0, "")
  ; Set index of bottom file
  $aRet[1] = $i
  ; Now look for top match
  For $i = $aRet[1] To 1 Step -1
   If StringRegExpReplace($avArray[$i], "(^.*)(.*)", "1") <> $vValue Then ExitLoop
  Next
  ; Set top match
  $aRet[0] = $i + 1
Else
  ; Set index of top associated file
  $aRet[0] = $i
  ; Now look for bottom match - find first file which does not match
  For $i = $aRet[0] To $avArray[0]
   If StringRegExpReplace($avArray[$i], "(^.*)(.*)", "1") <> $vValue Then ExitLoop
  Next
  ; Set bottom match
  $aRet[1] = $i - 1
EndIf
Return $aRet
EndFunc   ;==>_RFLTA_FileListSearch
Func _RFLTA_ArraySort(ByRef $avArray, $iStart = 1, $iEnd = -99)
If $iEnd = -99 Then $iEnd = UBound($avArray) - 1
_RFLTA_QuickSort($avArray, $iStart, $iEnd)
EndFunc   ;==>_RFLTA_ArraySort
Func _RFLTA_QuickSort(ByRef $avArray, ByRef $iStart, ByRef $iEnd)
Local $vTmp
If ($iEnd - $iStart) < 15 Then
  Local $i, $j, $vCur
  For $i = $iStart + 1 To $iEnd
   $vTmp = $avArray[$i]
   If IsNumber($vTmp) Then
    For $j = $i - 1 To $iStart Step -1
     $vCur = $avArray[$j]
     If ($vTmp >= $vCur And IsNumber($vCur)) Or (Not IsNumber($vCur) And StringCompare($vTmp, $vCur) >= 0) Then ExitLoop
     $avArray[$j + 1] = $vCur
    Next
   Else
    For $j = $i - 1 To $iStart Step -1
     If (StringCompare($vTmp, $avArray[$j]) >= 0) Then ExitLoop
     $avArray[$j + 1] = $avArray[$j]
    Next
   EndIf
   $avArray[$j + 1] = $vTmp
  Next
  Return
EndIf
Local $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)], $fNum = IsNumber($vPivot)
Do
  If $fNum Then
   While ($avArray[$L] < $vPivot And IsNumber($avArray[$L])) Or (Not IsNumber($avArray[$L]) And StringCompare($avArray[$L], $vPivot) < 0)
    $L += 1
   WEnd
   While ($avArray[$R] > $vPivot And IsNumber($avArray[$R])) Or (Not IsNumber($avArray[$R]) And StringCompare($avArray[$R], $vPivot) > 0)
    $R -= 1
   WEnd
  Else
   While (StringCompare($avArray[$L], $vPivot) < 0)
    $L += 1
   WEnd
   While (StringCompare($avArray[$R], $vPivot) > 0)
    $R -= 1
   WEnd
  EndIf
  If $L <= $R Then
   $vTmp = $avArray[$L]
   $avArray[$L] = $avArray[$R]
   $avArray[$R] = $vTmp
   $L += 1
   $R -= 1
  EndIf
Until $L > $R
_RFLTA_QuickSort($avArray, $iStart, $R)
_RFLTA_QuickSort($avArray, $L, $iEnd)
EndFunc   ;==>_RFLTA_QuickSort
Func _RFLTA_ArrayConcatenate(ByRef $avArrayTarget, Const ByRef $avArraySource)
Local $iUBoundTarget = UBound($avArrayTarget) - 1, $iUBoundSource = UBound($avArraySource)
ReDim $avArrayTarget[$iUBoundTarget + $iUBoundSource]
For $i = 1 To $iUBoundSource - 1
  $avArrayTarget[$iUBoundTarget + $i] = $avArraySource[$i]
Next
EndFunc   ;==>_RFLTA_ArrayConcatenate
Func _RFLTA_Progress($vProgress = "", $sTotal = 0)
$sCurrent_File = $sCurrent_File + 1
Return GUICtrlSetData($vProgress, $sCurrent_File * 100 / $sTotal)
EndFunc   ;==>_RFLTA_Progress

Follow the $Break variable to understand what i've done (ofc if you want :bye:), is there a good soluction (i've done it right?) or there is a better one?

By the way im still working to make the detection of the total number file in a directory/drive faster, but with not luck :doh:

Hi and thanks for this wonderful piece of code :oops: !

Edited by StungStang
Link to comment
Share on other sites

  • Moderators

StungStang,

Follow the $Break variable to understand what i've done

I did. :oops:

is there a good soluction (i've done it right?) or there is a better one?

I think you have very amply demonstrated why the idea of a progress bar for a deep recursive search is not a good idea - so at the very least you have done that right! Seriously, I really do think that you would do better using a marquee progress as I suggested earlier. :bye:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...