Jump to content

modified _FileListToArray to suport subdirectory


yidabu
 Share

Recommended Posts

here is my code:

;myFileListToArray:
;~ example:
;~ $sPath = "D:\AutoIt\article\autoitv3.0"
;~ $aFile = myFileListToArray($sPath, "\.au3$", 1, "zt_,_private,BackUp,images")
;~ If IsArray($aFile) Then 
;~  For $i = 1 To $aFile[0]  Step 1
;~      ConsoleWrite($i & "=" & $aFile[$i] & @CRLF)
;~  Next
;~ EndIf
;===============================================================================
;
; Description:      lists files or directory(subdirectory) in a specified path (Similar to using Dir with the /b /s Switch)
;                   列出目录下所有文件或文件夹,包括子文件夹.(yidabu.com注:autoit官方版本_FileListToArray不包括搜索子文件夹,也不支持正则表达式)
; Syntax:            myFileListToArray($sPath,$rPath=0, $iFlag = 0,$sPathExclude=0)
; Parameter(s):     $sPath = Path to generate filelist for 要搜索的路径
;                   $iFlag = determines weather to return file or folders or both
;                   $rPath = The regular expression to compare. StringRegExp Function Reference For details
;                   用于搜索的正则表达式,用法同StringRegExp函数
;                       $iFlag=0(Default) Return both files and folders 返回所有文件和文件夹
;                       $iFlag=1 Return files Only 仅返回文件
;                       $iFlag=2 Return Folders Only 仅返回文件夹
;                   $sPathExclude = when word in path, the file/folder will exclude,mulite words separate by comma(,)
;                   在路径中要要排除的词语,多个有,分隔
;
; Requirement(s):   autoit v3.2.2.0
; Return Value(s):  On Success - Returns an array containing the list of files and folders in the specified path
;                        On Failure - Returns the an empty string "" if no files are found and sets @Error on errors
;                       @Error=1 Path not found or invalid
;                       @Error=3 Invalid $iFlag
;                       @Error=4 No File(s) Found
;
; Author(s):        by http://www.yidabu.com 一大步成功社区  http://bbs.yidabu.com/forum-2-1.html
; update:           20070125                             
; Note(s):          The array returned is one-dimensional and is made up as follows:
;                   $array[0] = Number of Files\Folders returned 返回文件/文件夹的数量
;                   $array[1] = 1st File\Folder (not include $sPath) 第一个文件/文件夹
;                   $array[2] = 2nd File\Folder (not include $sPath)
;                   $array[3] = 3rd File\Folder (not include $sPath)
;                   $array[n] = nth File\Folder (not include $sPath)
;                   Special Thanks to SolidSnake <MetalGX91 at GMail dot com> (his _FileListToArray)
;===============================================================================



Func myFileListToArray($sPath, $rPath = 0, $iFlag = 0, $sPathExclude = 0)
    Local $asFileList[1]        ;yidabu.com提示因为要用递归调用$asFileList参数要单独出来
    $asFileList = myFileListToArrayTemp($asFileList, $sPath, $rPath, $iFlag, $sPathExclude)
    Return $asFileList
EndFunc   ;==>myFileListToArray

Func myFileListToArrayTemp(ByRef $asFileList, $sPath, $rPath = 0, $iFlag = 0, $sPathExclude = 0)
    Local $hSearch, $sFile
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 3, "")
    $hSearch = FileFindFirstFile($sPath & "\*")
    If $hSearch = -1 Then Return SetError(4, 4, "")
    While 1
        $sFile = FileFindNextFile($hSearch)
        If @error Then
            SetError(0)
            ExitLoop
        EndIf
        
        ;yidabu.com提示已经被排除的路径就不要搜索子目录了
        If $sPathExclude And StringLen($sPathExclude) > 0 Then $sPathExclude = StringSplit($sPathExclude, ",")
        $bExclude = False
        If IsArray($sPathExclude) Then
            For $ii = 1 To $sPathExclude[0] Step 1
                If StringInStr($sPath & "\" & $sFile, $sPathExclude[$ii]) Then
                    $bExclude = True
                    ExitLoop
                EndIf
            Next
        EndIf
        If $bExclude Then ContinueLoop
        
        Select
            Case StringInStr(FileGetAttrib($sPath & "\" & $sFile), "D") ;如果遇到目录
                Select
                    Case $iFlag = 1 ;求文件时就递归
                        myFileListToArrayTemp($asFileList, $sPath & "\" & $sFile, $rPath, $iFlag, $sPathExclude)
                        ContinueLoop    ;求文件时跳过目录
                    Case $iFlag = 2 Or $iFlag = 0   ;求目录时分两种情况
                        If $rPath Then  ;1如果要求对路径进行正则匹配
                            If Not StringRegExp($sPath & "\" & $sFile, $rPath, 0) Then  ;正则匹配失败就递归
                                myFileListToArrayTemp($asFileList, $sPath & "\" & $sFile, $rPath, $iFlag, $sPathExclude)
                                ContinueLoop    ;正则匹配失败时跳过本目录
                            Else    ;正则匹配成功就递归并把本目录加入匹配成功                               
                                myFileListToArrayTemp($asFileList, $sPath & "\" & $sFile, $rPath, $iFlag, $sPathExclude)
                            EndIf
                        Else    ;2如果不要求对路径进行正则匹配递归并把本目录加入匹配成功
                            myFileListToArrayTemp($asFileList, $sPath & "\" & $sFile, $rPath, $iFlag, $sPathExclude)
                        EndIf
                EndSelect
                
            Case Not StringInStr(FileGetAttrib($sPath & "\" & $sFile), "D") ;如果遇到文件
                If $iFlag = 2 Then ContinueLoop ;求目录时就跳过
                ;yidabu.com提示要求正则匹配路径且匹配失败时就跳过。遇文件就不要递归调用了。
                If $rPath And Not StringRegExp($sPath & "\" & $sFile, $rPath, 0) Then ContinueLoop
        EndSelect
        
        ReDim $asFileList[UBound($asFileList) + 1]
        $asFileList[0] = $asFileList[0] + 1
        $asFileList[UBound($asFileList) - 1] = $sPath & "\" & $sFile
        
    WEnd
    FileClose($hSearch)
    Return $asFileList
EndFunc   ;==>myFileListToArrayTemp

;myFileListToArray.
oÝ÷ ØLZ^ëmâçë¢`´÷f®¶­sbb33c¶F"Ò×fÆTÆ7EFô'&gV÷C¶3¢gV÷C²ÂgV÷C²b3#²çF×b33c²gV÷C²ÂÂgV÷C²gV÷C²¤f÷"b33c¶ÒFòb33c¶F%³Ò7FW 6öç6öÆUw&FRb33c¶F%²b33c¶ÒfײÄb¤æW@

the result:

c:\Documents and Settings\Administrator\Local Settings\Temp\qqs40.tmp

c:\Documents and Settings\Administrator\Local Settings\Temp\tem23.tmp

c:\Documents and Settings\Administrator\Local Settings\Temp\tem32.tmp

c:\Documents and Settings\Administrator\Local Settings\Temp\tem34.tmp

c:\Documents and Settings\Administrator\Local Settings\Temp\~DFD6D.tmp

c:\Documents and Settings\Administrator\Local Settings\Temp\~DFD75.tmp

Edited by yidabu

my UDF:myReplaceStringInFile suport StringRegExp and subdirectorymyFileListToArray suport StringRegExp and subdirectorymyImageIdentify get all information from image, use Image Magick com supportautoit in Chinaautoit 论坛yidabu成功社区

Link to comment
Share on other sites

Great!

I should rather change "$sFilter" to RegExp, It will be easy to handle

my UDF:myReplaceStringInFile suport StringRegExp and subdirectorymyFileListToArray suport StringRegExp and subdirectorymyImageIdentify get all information from image, use Image Magick com supportautoit in Chinaautoit 论坛yidabu成功社区

Link to comment
Share on other sites

  • Moderators

Great!

I should rather change "$sFilter" to RegExp, It will be easy to handle

:) Huh :D ?

$sFilter is handled through the Run() cmd... this method has proven to be much faster.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • 4 years later...

Hi all,

I have a two image folders .. i am comparing the both folder images.problem is when i am using FilelistToArray the image compared result is giving wrong.

please check my code what is the wrong in that ...help should apreciated....

I want to copmpare the both folder images...........

$aFile = _FileListToArray("c:\image1", "*.bmp*")

$aFile1 = _FileListToArray("c:\image2", '*.bmp*')

;If IsArray($aFile) Then

;MsgBox(0,"","ds")

For $i = 1 To 100

ConsoleWrite($i & "=" & $aFile[$i] & @CRLF)

ConsoleWrite($i & "=" & $aFile1[$i] & @CRLF)

$myfirst= MsgBox(0,"First", $aFile[$i])

$mysecond= MsgBox(0,"second", $aFile1[$i])

$ram=FileRead($aFile[$i])

$ram1=FileRead($aFile1[$i])

If $ram==$ram1 Then

MsgBox(0, "", " i am ")

Else

MsgBox(0, "", "i am not")

EndIf

; Next

Next

Edited by Mallikarjun
Link to comment
Share on other sites

  • Moderators

Mallikarjun,

First off, why dig up a 5 year old thread to post this? Next time just open a new thread. :oops:

Now to your problem:

When I use your script on 2 folders I get the results I expect - matching files return "i am" while non-matching files return "i am not". When you say "compared result is giving wrong" what is happening? Are you getting false matches or false mismatches? Are you sure that the files being compared are the same - that is that their indices within the arrays are the same? :D

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

it seems the fastest\clearest way

Examples near the end of this June 2009 thread are the fastest recursive _FileListToArray() functions I've seen to date:

Here's a speed comparison of the function from post #252 of that thread versus your (very nice) routine:

#include <Array.au3>
Global $parm[4][3] = [["*", 0, 0], _ ; basic search
          ["*", 0, 2], _ ; full pathname
          ["*", 2, 0], _ ; folders only
          ["d*", 0, 0]]  ; name filter
Global $ret[4][2], $array
For $x = 0 to 3
$ret[$x][1] = TimerInit()
For $y = 1 to 5
  $array = _FileListToArrayRec(@WindowsDir, "", $parm[$x][0], "", $parm[$x][1], $parm[$x][2], 1)
Next
$ret[$x][1] = TimerDiff($ret[$x][1])
$ret[$x][0] = $array[0]
; _ArrayDisplay($array)
Next
MsgBox(0, "",  "Basic Search: " & $ret[0][0] & " in " & Round($ret[0][1]/1000, 2) & " seconds" & @CRLF & _
    "Full Path   : " & $ret[1][0] & " in " & Round($ret[1][1]/1000, 2) & " seconds" & @CRLF & _
    "Folders Only: " & $ret[2][0] & " in " & Round($ret[2][1]/1000, 2) & " seconds" & @CRLF & _
    "Name Filter : " & $ret[3][0] & " in " & Round($ret[3][1]/1000, 2) & " seconds" & @CRLF & _
    "Total     : " & Round(($ret[0][1]+$ret[1][1]+$ret[2][1]+$ret[3][1])/1000, 2) & " seconds")
 
Global $parm[4][3] = [["*", 0, 1], _ ; basic search
          ["*", 0, 2], _ ; full pathname
          ["*", 2, 1], _ ; folders only
          ["d*", 0, 1]]  ; name filter
Global $ret[4][2], $array
For $x = 0 to 3
$ret[$x][1] = TimerInit()
For $y = 1 to 5
  $array = _FileListToArrayEx(@WindowsDir, $parm[$x][0], $parm[$x][1], $parm[$x][2])
Next
$ret[$x][1] = TimerDiff($ret[$x][1])
$ret[$x][0] = $array[0]
; _ArrayDisplay($array)
Next
MsgBox(0, "",  "Basic Search: " & $ret[0][0] & " in " & Round($ret[0][1]/1000, 2) & " seconds" & @CRLF & _
    "Full Path   : " & $ret[1][0] & " in " & Round($ret[1][1]/1000, 2) & " seconds" & @CRLF & _
    "Folders Only: " & $ret[2][0] & " in " & Round($ret[2][1]/1000, 2) & " seconds" & @CRLF & _
    "Name Filter : " & $ret[3][0] & " in " & Round($ret[3][1]/1000, 2) & " seconds" & @CRLF & _
    "Total     : " & Round(($ret[0][1]+$ret[1][1]+$ret[2][1]+$ret[3][1])/1000, 2) & " seconds")
 
Func _FileListToArrayRec($sPath, $sExcludeFolderList = "", $sIncludeList = "*", $sExcludeList = "", $iReturnType = 0, $iReturnFormat = 0, $bRecursive = False)
    Local $sRet = "", $sReturnFormat = ""
    ; Edit include path (strip trailing slashes, and append single slash)
    $sPath = StringRegExpReplace($sPath, "[\\/]+\z", "") & "\"
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    ; Edit exclude folders list
;   If $sExcludeFolderList Then
        ; Strip leading/trailing spaces and semi-colons, any adjacent semi-colons, and spaces surrounding semi-colons
;       $sExcludeFolderList = StringRegExpReplace(StringRegExpReplace($sExcludeFolderList, "(\s*;\s*)+", ";"), "\A;|;\z", "")
        ; Convert to Regular Expression, step 1: Wrap brackets around . and $ (what other characters needed?)
;       $sExcludeFolderList = StringRegExpReplace($sExcludeFolderList, '[.$]', '\[\0\]')
        ; Convert to Regular Expression, step 2: Convert '?' to '.', and '*' to '.*?'
;       $sExcludeFolderList = StringReplace(StringReplace($sExcludeFolderList, "?", "."), "*", ".*?")
        ; Convert to Regular Expression, step 3; case-insensitive, convert ';' to '|', match from first char, terminate strings
;       $sExcludeFolderList = "(?i)\A(?!" & StringReplace($sExcludeFolderList, ";", "$|")  & "$)"
;   EndIf
    ; Edit include files list
    If $sIncludeList = "*" Then
        $sIncludeList = ""
    Else
        If StringRegExp($sIncludeList, "[\\/ :> <\|]|(?s)\A\s*\z") Then Return SetError(2, 2, "")
        ; Strip leading/trailing spaces and semi-colons, any adjacent semi-colons, and spaces surrounding semi-colons
        $sIncludeList = StringRegExpReplace(StringRegExpReplace($sIncludeList, "(\s*;\s*)+", ";"), "\A;|;\z", "")
        ; Convert to Regular Expression, step 1: Wrap brackets around . and $ (what other characters needed?)
        $sIncludeList = StringRegExpReplace($sIncludeList, '[.$]', '\[\0\]')
        ; Convert to Regular Expression, step 2: Convert '?' to '.', and '*' to '.*?'
        $sIncludeList = StringReplace(StringReplace($sIncludeList, "?", "."), "*", ".*?")
        ; Convert to Regular Expression, step 3; case-insensitive, convert ';' to '|', match from first char, terminate strings
        $sIncludeList = "(?i)\A(" & StringReplace($sIncludeList, ";", "$|")  & "$)"
    EndIf
    ; Edit exclude files list
;   If $sExcludeList Then
        ; Strip leading/trailing spaces and semi-colons, any adjacent semi-colons, and spaces surrounding semi-colons
;       $sExcludeList = StringRegExpReplace(StringRegExpReplace($sExcludeList, "(\s*;\s*)+", ";"), "\A;|;\z", "")
        ; Convert to Regular Expression, step 1: Wrap brackets around . and $ (what other characters needed?)
;       $sExcludeList = StringRegExpReplace($sExcludeList, '[.$]', '\[\0\]')
        ; Convert to Regular Expression, step 2: Convert '?' to '.', and '*' to '.*?'
;       $sExcludeList = StringReplace(StringReplace($sExcludeList, "?", "."), "*", ".*?")
        ; Convert to Regular Expression, step 3; case-insensitive, convert ';' to '|', match from first char, terminate strings
;       $sExcludeList = "(?i)\A(?!" & StringReplace($sExcludeList, ";", "$|")  & "$)"
;   EndIf
;   MsgBox(1,"Masks","File include: " & $sIncludeList & @CRLF & "File exclude: " & $sExcludeList & @CRLF _
;          & "Dir exclude : " & $sExcludeFolderList)
    If Not ($iReturnType = 0 Or $iReturnType = 1 Or $iReturnType = 2) Then Return SetError(3, 3, "")
    Local $sOrigPathLen = StringLen($sPath), $aQueue[64] = [1,$sPath], $iQMax = 63
    While $aQueue[0]
        $WorkFolder = $aQueue[$aQueue[0]]
        $aQueue[0] -= 1
        $search = FileFindFirstFile($WorkFolder & "*") ; get full list of current folder
        If @error Then ContinueLoop
        Switch $iReturnFormat
            Case 1 ; relative path
                $sReturnFormat = StringTrimLeft($WorkFolder, $sOrigPathLen)
            Case 2 ; full path
                $sReturnFormat = $WorkFolder
        EndSwitch
        While 1 ; process current folder
            $file = FileFindNextFile($search)
            If @error Then ExitLoop
            If @extended Then ; Folder
;              If $sExcludeFolderList And Not StringRegExp($file, $sExcludeFolderList) Then ContinueLoop
                If $bRecursive Then ; push folder onto queue
                    If $aQueue[0] = $iQMax Then
                        $iQMax += 128
                        ReDim $aQueue[$iQMax + 1]
                    EndIf
                    $aQueue[0] += 1
                    $aQueue[$aQueue[0]] = $WorkFolder & $file & "\"
                EndIf
                If $iReturnType = 1 Then ContinueLoop
            Else ; File
                If $iReturnType = 2 Then ContinueLoop
            EndIf
            If $sIncludeList And Not StringRegExp($file, $sIncludeList) Then ContinueLoop
;           If $sExcludeList And Not StringRegExp($file, $sExcludeList) Then ContinueLoop
            $sRet &= $sReturnFormat & $file & "|" ; append to output
        WEnd
        FileClose($search)
    WEnd
    If Not $sRet Then Return SetError(4, 4, "")
    Return StringSplit(StringTrimRight($sRet, 1), "|")
EndFunc
Func _FileListToArrayEx($sPath, $sFilter = "*", $iFlag = 0, $sSDir = 0)
    Local $hSearch, $sFile, $sFileList, $sDelim = "|", $sSDirFTMP = $sFilter
    $sPath = StringRegExpReplace($sPath, "[\\/]+\z", "") & "\" ; ensure single trailing backslash
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    If StringRegExp($sFilter, "[\\/:><\|]|(?s)\A\s*\z") Then Return SetError(2, 2, "")
    If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 3, "")
    If $sSDir Then $sFilter = "*"
    $hSearch = FileFindFirstFile($sPath & $sFilter)
    If @error Then Return SetError(4, 4, "")
    Local $hWSearch = $hSearch, $hWSTMP = $hSearch, $SearchWD, $FPath = StringRegExpReplace(StringRegExpReplace($sSDir, '[^2]+', ""), "2+", StringRegExpReplace($sPath, '\\', "\\\\")), $sSDirF[3] = [0, StringReplace($sSDirFTMP, "*", ""), "(?i)" & StringRegExpReplace(StringRegExpReplace(StringRegExpReplace(StringRegExpReplace($sSDirFTMP, '[\^\$\(\)\+\[\]\{\}\,\.\=]', "\\$0"), "^[^\*]", "^$0"), "[^\*]$", "$0\$"), '\*', ".*")]
    While 1
        $sFile = FileFindNextFile($hWSearch)
        If @error Then
            If $hWSearch = $hSearch Then ExitLoop
            FileClose($hWSearch)
            $hWSearch -= 1
            $SearchWD = StringLeft($SearchWD, StringInStr(StringTrimRight($SearchWD, 1), "\", 0, -1))
        ElseIf $sSDir Then
            $sSDirF[0] = @extended
            If ($iFlag + $sSDirF[0] <> 2) Then
                If $sSDirF[1] Then
                    If StringRegExp($sFile, $sSDirF[2]) Then $sFileList &= $sDelim & $FPath & $SearchWD & $sFile
                Else
                    $sFileList &= $sDelim & $FPath & $SearchWD & $sFile
                EndIf
            EndIf
            If Not $sSDirF[0] Then ContinueLoop
            $hWSTMP = FileFindFirstFile($sPath & $SearchWD & $sFile & "\*")
            If $hWSTMP = -1 Then ContinueLoop
            $hWSearch = $hWSTMP
            $SearchWD &= $sFile & "\"
        Else
            If ($iFlag + @extended = 2) Then ContinueLoop
            $sFileList &= $sDelim & $sFile
        EndIf
    WEnd
    FileClose($hSearch)
    If Not $sFileList Then Return SetError(4, 4, "")
    Return StringSplit(StringTrimLeft($sFileList, 1), "|")
EndFunc
Edited by Spiff59
Link to comment
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
 Share

  • Recently Browsing   0 members

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