Jump to content

Improvement of included _FileListToArray function.


Tlem
 Share

Recommended Posts

OK, but what is the strangest, it is that the function _FileListToArrayNT does not raise this problem...

I tested practically quite the functions _FileListToArrayNT up to the version 7 that you have release here : #702862

Thus this is typically bound to the functions _FileListToArrayNT, _FileListToArrayEx and _FileListToArray3... ;)

Best Regards.Thierry

Link to comment
Share on other sites

  • Replies 265
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

@Tiem

Good news, Problem is solved!

It was my fault, FileClose is the magic function.

(you have been on the right track)

So nothing is wrong with FileExists, FileFindFirstFile, FileFindNextFile or DirRemove.

(I should always read the help-section to the end !!! mea culpa) :);)

A quick and dirty solution:

I have consequently added FileClose, so _FileListToArrayXT seems to work right now (i hope so).

Please test the function and give feedback.

I do apologize about the bug in _FileListToArrayXT.

BaKaMu

; #FUNCTION# ===========================================================================================
; Name:             _FileListToArrayXT
; Description:      Lists files and\or folders in specified path(s) (Similar to using Dir with the /B Switch)
;                   additional features: multi-path, multi-filter, multi-exclude-filter, path format options, recursive search
;                   Corrected on 2010/08/19: Added FileClose()
; Syntax:           _FileListToArrayXT([$sPath = @ScriptDir, [$sFilter = "*", [$iRetItemType, [$bRecursive = False, [$sExclude = "", [$iRetFormat = 1]]]]]])
; Parameter(s):     $sPath = optional: Search path(s), semicolon delimited (default: @ScriptDir)
;                            (Example: "C:\Tmp;D:\Temp")
;                   $sFilter = optional: Search filter(s), semicolon delimited . Wildcards allowed. (default: "*")
;                              (Example: "*.exe;*.txt")
;                   $iRetItemType = Include in search: 0 = Files and Folder, 1 = Files Only, 2 = Folders Only
;                   $iRetPathType = Returned element format: 0 = file/folder name only, 1 = relative path, 2 = full path
;                   $bRecursive = optional: True: recursive search including all subdirectories
;                                           False (default): search only in specified folder
;                   $sExclude = optional: Exclude filter(s), semicolon delimited. Wildcards allowed.
;                               (Example: "Unins*" will remove all files/folders that begin with "Unins")
;                   $iRetFormat =  optional: return format
;                                  0 = one-dimensional array, 0-based
;                                  1 = one-dimensional array, 1-based (default)
;                                  2 = String ( "|" delimited)
; Requirement(s):   AutoIt Version 3.3.1.1 or newer
; Return Value(s):  on success: 1-based or 0-based array or string (dependent on $iRetFormat)
;                   If no path is found, @error and @extended are set to 1, returns empty string
;                   If no filter is found, @error and @extended are set to 2, returns empty string
;                   If $iRetFormat is invalid, @error and @extended are set to 3, returns empty string
;                   If no data is found, @error and @extended are set to 4, returns empty string
; Author(s):        Half the AutoIt Community
; ====================================================================================================
Func _FileListToArrayXT($sPath = @ScriptDir, $sFilter = "*", $iRetItemType = 0, $iRetPathType = 0, $bRecursive = False, $sExclude = "", $iRetFormat = 1)
  Local $hSearchFile, $sFile, $sFileList, $sWorkPath, $sRetPath, $iRootPathLen, $iPCount, $iFCount, $fDirFlag

  ;[check and prepare parameters]
  ;---------------
  If $sPath = -1 Or $sPath = Default Then $sPath = @ScriptDir
  ;strip leading/trailing spaces and semi-colons, all adjacent semi-colons, and spaces surrounding semi-colons
  $sPath = StringRegExpReplace(StringRegExpReplace($sPath, "(\s*;\s*)+", ";"), "\A;|;\z", "")
  ;check that at least one path is set
  If $sPath = "" Then Return SetError(1, 1, "")
  ;-----
  If $sFilter = -1 Or $sFilter = Default Then $sFilter = "*"
  ;prepare filter
  ;strip leading/trailing spaces and semi-colons, all adjacent semi-colons, and spaces surrounding semi-colons
  $sFilter = StringRegExpReplace(StringRegExpReplace($sFilter, "(\s*;\s*)+", ";"), "\A;|;\z", "")
  ;check for invalid chars or that at least one filter is set
  If StringRegExp($sFilter, "[\\/><:\|]|(?s)\A\s*\z") Then Return SetError(2, 2, "")
  If $bRecursive Then
    ;Convert $sFilter for Regular Expression
    $sFilter = StringRegExpReplace($sFilter, '([\Q\.+[^]$(){}=!\E])', '\\$1')
    $sFilter = StringReplace($sFilter, "?", ".")
    $sFilter = StringReplace($sFilter, "*", ".*?")
    $sFilter = "(?i)\A(" & StringReplace($sFilter, ";", "$|") & "$)" ;case-insensitive, convert ';' to '|', match from first char, terminate strings
    ;$sFilter = "(?i)\A" & StringReplace($sFilter, ";", "|") & "\z"
  EndIf
  ;-----
  If $iRetItemType <> "1" And $iRetItemType <> "2" Then $iRetItemType = "0"
  ;-----
  If $iRetPathType <> "1" And $iRetPathType <> "2" Then $iRetPathType = "0"
  ;-----
  $bRecursive = ($bRecursive = "1")
  ;-----
  If $sExclude = -1 Or $sExclude = Default Then $sExclude = ""
  If $sExclude Then
    ;prepare $sExclude
    ;strip leading/trailing spaces and semi-colons, all adjacent semi-colons, and spaces surrounding semi-colons
    $sExclude = StringRegExpReplace(StringRegExpReplace($sExclude, "(\s*;\s*)+", ";"), "\A;|;\z", "")
    ;Convert $sExclude for Regular Expression
    $sExclude = StringRegExpReplace($sExclude, '([\Q\.+[^]$(){}=!\E])', '\\$1')
    $sExclude = StringReplace($sExclude, "?", ".")
    $sExclude = StringReplace($sExclude, "*", ".*?")
    $sExclude = "(?i)\A(" & StringReplace($sExclude, ";", "$|") & "$)" ;case-insensitive, convert ';' to '|', match from first char, terminate strings
    ;$sExclude = "(?i)\A" & StringReplace($sExclude, ";", "|") & "\z"
  EndIf
  ;-----
  ;If $iRetFormat <> "0" And $iRetFormat <> "2" Then $iRetFormat = "1"
  If Not ($iRetItemType = 0 Or $iRetItemType = 1 Or $iRetItemType = 2) Then Return SetError(3, 3, "")
  ;---------------
  ;[/check and prepare parameters]

  ;---------------

  Local $aPath = StringSplit($sPath, ';', 1) ;paths array
  Local $aFilter = StringSplit($sFilter, ';', 1) ;filters array

  ;---------------

  If $bRecursive Then ;different handling for recursion (strategy: unfiltered search for all items and filter unwanted)

    If $sExclude Then ;different handling dependent on $sExclude parameter is set or not

      For $iPCount = 1 To $aPath[0] ;Path loop
        $sPath = StringRegExpReplace($aPath[$iPCount], "[\\/]+\z", "") & "\" ;ensure exact one trailing slash
        If Not FileExists($sPath) Then ContinueLoop
        $iRootPathLen = StringLen($sPath) - 1

        Local $aPathStack[1024] = [1, $sPath]

        While $aPathStack[0] > 0
          $sWorkPath = $aPathStack[$aPathStack[0]]
          $aPathStack[0] -= 1
          ;-----
          $hSearchFile = FileFindFirstFile($sWorkPath & '*')
          If @error Then
            FileClose($hSearchFile)
            ContinueLoop
          EndIf
          ;-----
          Switch $iRetPathType
            Case 2 ;full path
              $sRetPath = $sWorkPath
            Case 1 ;relative path
              $sRetPath = StringTrimLeft($sWorkPath, $iRootPathLen + 1)
          EndSwitch
          ;-----
          Switch $iRetItemType
            Case 1
              While True ;Files only
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                $fDirFlag = @extended
                If $fDirFlag Then
                  $aPathStack[0] += 1
                  If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
                  $aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & "\"
                  ContinueLoop
                EndIf
                If StringRegExp($sFile, $sExclude) Then ContinueLoop
                If StringRegExp($sFile, $sFilter) Then
                  $sFileList &= $sRetPath & $sFile & "|"
                EndIf
              WEnd
            Case 2
              While True ;Folders only
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                $fDirFlag = @extended
                If StringRegExp($sFile, $sExclude) Then ContinueLoop
                If $fDirFlag Then
                  $aPathStack[0] += 1
                  If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
                  $aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & "\"
                  If StringRegExp($sFile, $sFilter) Then
                    $sFileList &= $sRetPath & $sFile & "|"
                  EndIf
                EndIf
              WEnd
            Case Else
              While True ;Files and Folders
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                $fDirFlag = @extended
                If StringRegExp($sFile, $sExclude) Then ContinueLoop
                If $fDirFlag Then
                  $aPathStack[0] += 1
                  If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
                  $aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & "\"
                EndIf
                If StringRegExp($sFile, $sFilter) Then
                  $sFileList &= $sRetPath & $sFile & "|"
                EndIf
              WEnd
          EndSwitch
          ;-----
        WEnd

        FileClose($hSearchFile)

      Next ;$iPCount - next path

    Else ;If Not $sExclude

      For $iPCount = 1 To $aPath[0] ;Path loop
        $sPath = StringRegExpReplace($aPath[$iPCount], "[\\/]+\z", "") & "\" ;ensure exact one trailing slash
        If Not FileExists($sPath) Then ContinueLoop
        $iRootPathLen = StringLen($sPath) - 1

        Local $aPathStack[1024] = [1, $sPath]

        While $aPathStack[0] > 0
          $sWorkPath = $aPathStack[$aPathStack[0]]
          $aPathStack[0] -= 1
          ;-----
          $hSearchFile = FileFindFirstFile($sWorkPath & '*')
          If @error Then
            FileClose($hSearchFile)
            ContinueLoop
          EndIf
          ;-----
          Switch $iRetPathType
            Case 2 ;full path
              $sRetPath = $sWorkPath
            Case 1 ;relative path
              $sRetPath = StringTrimLeft($sWorkPath, $iRootPathLen + 1)
          EndSwitch
          ;-----
          Switch $iRetItemType
            Case 1
              While True ;Files only
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                If @extended Then
                  $aPathStack[0] += 1
                  If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
                  $aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & "\"
                  ContinueLoop
                EndIf
                If StringRegExp($sFile, $sFilter) Then
                  $sFileList &= $sRetPath & $sFile & "|"
                EndIf
              WEnd
            Case 2
              While True ;Folders only
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                If @extended Then
                  $aPathStack[0] += 1
                  If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
                  $aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & "\"
                  If StringRegExp($sFile, $sFilter) Then
                    $sFileList &= $sRetPath & $sFile & "|"
                  EndIf
                EndIf
              WEnd
            Case Else
              While True ;Files and Folders
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                If @extended Then
                  $aPathStack[0] += 1
                  If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
                  $aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & "\"
                EndIf
                If StringRegExp($sFile, $sFilter) Then
                  $sFileList &= $sRetPath & $sFile & "|"
                EndIf
              WEnd
          EndSwitch
          ;-----
        WEnd

        FileClose($hSearchFile)

      Next ;$iPCount - next path

    EndIf ;If $sExclude

  Else ;If Not $bRecursive (strategy: filtered search for items)

    If $sExclude Then ;different handling dependent on $sExclude parameter is set or not

      For $iPCount = 1 To $aPath[0] ;Path loop

        $sPath = StringRegExpReplace($aPath[$iPCount], "[\\/]+\z", "") & "\" ;ensure exact one trailing slash
        If Not FileExists($sPath) Then ContinueLoop
        ;-----
        Switch $iRetPathType
          Case 2 ;full path
            $sRetPath = $sPath
          Case 1 ;relative path
            $sRetPath = ""
        EndSwitch

        For $iFCount = 1 To $aFilter[0] ;filter loop
          ;-----
          $hSearchFile = FileFindFirstFile($sPath & $aFilter[$iFCount])
          If @error Then
            FileClose($hSearchFile)
            ContinueLoop
          EndIf
          ;-----
          Switch $iRetItemType
            Case 1 ;files Only
              While True
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                If @extended Then ContinueLoop ;bypass folder
                ;check for exclude files
                If StringRegExp($sFile, $sExclude) Then ContinueLoop
                $sFileList &= $sRetPath & $sFile & "|"
              WEnd
            Case 2 ;folders Only
              While True
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                If @extended Then ;bypass file
                  ;check for exclude folder
                  If StringRegExp($sFile, $sExclude) Then ContinueLoop
                  $sFileList &= $sRetPath & $sFile & "|"
                EndIf
              WEnd
            Case Else ;files and folders
              While True
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                ;check for exclude files/folder
                If StringRegExp($sFile, $sExclude) Then ContinueLoop
                $sFileList &= $sRetPath & $sFile & "|"
              WEnd
          EndSwitch
          FileClose($hSearchFile)
        Next ;$iFCount - next filter

      Next ;$iPCount - next path

    Else ;If Not $sExclude

      For $iPCount = 1 To $aPath[0] ;Path loop

        $sPath = StringRegExpReplace($aPath[$iPCount], "[\\/]+\z", "") & "\" ;ensure exact one trailing slash
        If Not FileExists($sPath) Then ContinueLoop
        ;-----
        Switch $iRetPathType
          Case 2 ;full path
            $sRetPath = $sPath
          Case 1 ;relative path
            $sRetPath = ""
        EndSwitch

        For $iFCount = 1 To $aFilter[0] ;filter loop
          ;-----
          $hSearchFile = FileFindFirstFile($sPath & $aFilter[$iFCount])
          If @error Then
            FileClose($hSearchFile)
            ContinueLoop
          EndIf
          ;-----
          Switch $iRetItemType
            Case 1 ;files Only
              While True
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                If @extended Then ContinueLoop ;bypass folder
                $sFileList &= $sRetPath & $sFile & "|"
              WEnd
            Case 2 ;folders Only
              While True
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                If @extended Then ;bypass file
                  $sFileList &= $sRetPath & $sFile & "|"
                EndIf
              WEnd
            Case Else ;files and folders
              While True
                $sFile = FileFindNextFile($hSearchFile)
                If @error Then
                  FileClose($hSearchFile)
                  ExitLoop
                EndIf
                $sFileList &= $sRetPath & $sFile & "|"
              WEnd
          EndSwitch
          FileClose($hSearchFile)
        Next ;$iFCount - next filter

      Next ;$iPCount - next path

    EndIf ;If $sExclude

  EndIf ;If $bRecursive

  ;---------------

  ;set according return value
  If $sFileList Then
    Switch $iRetFormat
      Case 2 ;return a delimited string
        Return StringTrimRight($sFileList, 1)
      Case 0 ;return a 0-based array
        Return StringSplit(StringTrimRight($sFileList, 1), "|", 2)
      Case Else ;return a 1-based array
        Return StringSplit(StringTrimRight($sFileList, 1), "|", 1)
    EndSwitch
  Else
    Return SetError(4, 4, "")
  EndIf

EndFunc   ;==>_FileListToArrayXT
Link to comment
Share on other sites

I am really surprised that you apologize for a work which in summer made in group... ;)

But it is everything in your honor.

Having made quite a lot of tries, I regret noticing that there is an extremely strange problem.

If I create dirs with the script or in the hand, all is ok, but unfortunately for my testings I use another method.

I have created the structure in a dir that I call _Test1. When I want to make my trys, I use Explorer to duplicate the source dir and I rename it Test1 (I do it also with the script, and the result is the same).

When I made as it, _FileListToArrayXT fail while _FileListToArrayNT work. :P

I think it's something in relation with Windows, but I really don't understand why.

The ultimate is that if I launch the script twice, the function _FileListToArrayXT works. :)

I think that I am going crazy (if it is not already made). ;)

Best Regards.Thierry

Link to comment
Share on other sites

  • 3 years later...
  • Moderators

fxg4758,

Do you realise that there is now a recursive function within the standard istall - _FileListToArrayRec? Have you tried that over your network? :huh:

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

  • 4 weeks later...

Hi all. I use this function to delete files in local folders, but when i use in network it fails. Can someone help me? Regards

 

This thread contains many different versions, so when you say you use "this function" it's hard to know what you're running.

Whichever you'd chosen, you were unlucky as most in this thread support UNC names.

Try the 65-liner in post #252.

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...