Jump to content
Sign in to follow this  
senthor

_FileListTreeToArray UDF

Recommended Posts

senthor

Hi!

After several questions, I created this UDF.

Comments:

; Name...........: _FileListTreeToArray
; Description ...: List all files from the wished directory with all files from all subfolders to an array.
; Syntax.........: _FileListTreeToArray($pFolder[, $tPath = 1[, $tType = 0]])
; Parameters ....: $pFolder - Path to the directory that has to be listed
;                 $tPath   - Optional: Path return type, "0" = absolute (default), "1" = relative
;                 $tType   - Optional: Search type, see "cmd.exe /K dir /?" at subpoint attributes
;                                Or see helptopic "FileGetAttrib"
;                          - Possible attributes: "RASHD"
;                                R: Readonly
;                                A: Archive
;                                S: System
;                                H: Hidden
;                                D: Directory
;                          - Combine with using different operators together, it's like a logical "AND" operator
;                                f.ex. "DR", will retrieve readonly directories
;                          - Exclude with a "-" before the operator, it's like a logical "AND NOT" operator
;                                f.ex. "D-R" will retrieve non readonly directories
;                          - Default: "", all files
;                 $tSort   - Optional: Sort results, see "cmd.exe /K dir /?" at subpoint order
;                          - Possible orders:
;                                N: Name, alphabetically
;                                S: Size, smaller files first
;                                E: Extension, alphabetically
;                                D: Date/Time, older files first
;                                G: Directories first
;                          - Not combineable
;                          - Turn over order by using a "-" before the operator
;                                f.ex. "-S" will retrieve big files first
;                          - Default: "N", names sorted alphabetically
; Return values .: Success  - Array with $array[0] = Number of files\folders returned, $array[n] = path of file/folder
;                  Failure: - Returns 0 and sets @error to:
;                                 0 if directory doen't exists
;                                 1 if Flags are wrong
;                                 2 if any other error occurs
;                             If @error = 2 then @extended will be set to:
;                                 1 if an OemToChar error occurs
;                                 2 if a Split error occurs
; Author ........: Jonas Neef, Thanks to bernd670 for Ascii help
; Remarks .......: Can take very long, needs CPU; Files with special chars may result in some other string, f.ex. "µ" -> "æ"
; Related .......: FileGetAttrib, FileSetAttrib, _FileListToArray
; Link ..........; http://www.gigahard.de.hm
; Example .......; No

Download: FileEx.au3

senthor

Edited by senthor

Share this post


Link to post
Share on other sites
zaini

good script,

it help me much for future use...

thanx :)

Edited by zaini

Share this post


Link to post
Share on other sites
KaFu

Nice job, but... I took a look into a lot of FileListTo() functions for my program SMF. What i found was that all functions using DOS commands lack the one or the other feature. One Problem (filenames with non-standard characters) you address using the OEM2ANSI dll call, which works in most circumstanced, another way I tested was

$foo = Run(@ComSpec, "", @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
StdinWrite($foo, "chcp 1252" & @CRLF) ; change codepage for cmd.exe instance to 1252 (West European Latin)
StdinWrite($foo, "dir" & @CRLF)
StdinWrite($foo, "exit" & @CRLF) ; send exit command to trigger stdout
While 1
    $line &= StdoutRead($foo)
    If @error Then ExitLoop
Wend

but in most cases is not all, try to find a file with a

` character in the name and you'll see that it's translated into '

I don't know but guess, that this will happen with other foreign characters too.

The only solution I came up with finding all characters was a function using FileFindFirst() and FileFindNext(). To include sub-dir's you'll have to re-call the function for files found with the FileAttrib() D and put everything in an array.

Best Regards

Edited by KaFu

Share this post


Link to post
Share on other sites
uteotw

Most excellent, I needed something like this for a long time. Thanks a lot.

Now, I've found a small problem with it when I loop through folders very quickly my script (compiled or not) would "randomly" hang!

I tracked it down to this UDF and I've just made a couple tweaks to make it more reliable:

- added Local declaration to 3 variables, which is necessary when using Opt("MustDeclareVars", 1) in your scripts

- added ProcessWaitClose, not sure if it's really necessary but it doesn't hurt

- used DllOpen / DllClose

Func _FileListTreeToArray($pFolder, $tPath = 0, $tType = "", $tSort = "N")
    Local $wCheck = StringSplit(StringLeft($pFolder, 3), ":" )  ; <<< my tweak ... declared $wCheck
    If $wCheck[0] <> 2 and StringLeft($pFolder, 1) <> "\" then $pFolder = @WorkingDir & "\" & $pFolder
    If $wCheck[0] <> 2 and StringLeft($pFolder, 1) = "\" then $pFolder = @WorkingDir & $pFolder
    If StringRight($pFolder, 1) = "\" then $pFolder = StringTrimRight($pFolder, 1)
    If Not FileExists($pFolder) then Return Seterror(0, 0, 0)
    if $tPath > 1 OR $tPath < 0 then return Seterror(1, 0, 0)
    Local $wSort = StringReplace($tSort, "-", "")   ; <<< my tweak ... declared $wSort
    If StringLen($wSort) <> 1 or $wSort <> "N" and $wSort <> "S" and $wSort <> "E" and $wSort <> "D" and $wSort <> "G" and _
        $wSort <> "" then return Seterror(1, 0, 0)
    If Stringreplace(Stringreplace(Stringreplace( Stringreplace(Stringreplace(Stringreplace($tType, "-", ""), "H", ""), "S", _
        ""), "A", ""), "R", ""), "D", "") <> "" then return Seterror(1,0,0)
    local $uArray, $iStdout, $sTemp, $placeholder
    If $tType = "" Then
        $iStdout = Run(@comspec & ' /C cd ..\..\..\..\.. & dir "' & $pFolder & '" /A /B /O:' & $tSort & ' /S', @workingdir, _
            @SW_HIDE, 6)
    Else
        $iStdout = Run(@comspec & ' /C cd ..\..\..\..\.. & dir "' & $pFolder & '" /A:' & $tType & ' /B /O:' & $tSort & ' /S', _
            @workingdir, @SW_HIDE, 6)
    EndIF
    Local $line ; <<< my tweak ... declared $line
    While 1
        $line = StdoutRead($iStdout)
        If @error Then ExitLoop
        If $line <> "" then $sTemp &= $line
    Wend
    ProcessWaitClose($iStdout)  ; <<<< my tweak ... might be necessary in case of sub-processed?
    For $i = 0 To StringLen($sTemp)
        $placeholder &= "  "
    Next
    Local $dll = DllOpen("user32.dll")  ; <<<< my tweak ... dllopen
    $sTemp = DllCall($dll, "long", "OemToChar", "str", $sTemp, "str", $placeholder)
    DllClose($dll)  ; <<<< my tweak ... dllclose
    If Not Isarray($sTemp) or $sTemp[0] < 1 then return Seterror(2,1,0)
    $sTemp = $sTemp[2]
    $sTemp = StringReplace($sTemp, @crlf, @lf)
    $sTemp = StringReplace($sTemp, @cr, @lf)
    If StringRight($sTemp, 1) = @lf then $sTemp = StringTrimRight($sTemp, 1)
    If StringLeft($sTemp, 1) = @lf then $sTemp = StringTrimLeft($sTemp, 1)
    If Not StringInStr($sTemp, @lf) then
        If $sTemp = "" then
            local $return[1] = [0]
        Else
            local $return[2] = [1, $sTemp]
        EndIf
    Else
        local $return = StringSplit($sTemp, @lf)
    EndIF
    if not isarray($return) then
        Return Seterror(2,2,0)
    EndIF
    If $tPath = 1 Then
        For $dArray = 1 To $return[0] Step 1
            $return[$dArray] = StringReplace($return[$dArray], $pFolder & "\", "")
        Next
    EndIf
    return Seterror(0,0,$return)
EndFunc   ;==>_FileReadTreeInArray

Now, my scripts don't hang anymore :)

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.