找回密码
 加入
搜索
查看: 5472|回复: 9

[效率算法] 【已解决】修改myFileListToArray()以高效和可自定义排除目录或文件名

  [复制链接]
发表于 2011-2-2 15:05:26 | 显示全部楼层 |阅读模式
本帖最后由 touch_xu 于 2011-2-24 05:13 编辑

主要目的两个,一可以自定义排除目录名或文件名,二是要高效,有其它方法更是求之不得了。
参考代码:
http://autoitx.com/forum.php?mod ... F%C2%BC%CB%D1%CB%F7

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
 楼主| 发表于 2011-2-2 16:06:18 | 显示全部楼层
等高手出现
发表于 2011-2-3 21:59:40 | 显示全部楼层
实际上 _FileListToArray 已经很高效了...舍近求远
 楼主| 发表于 2011-2-4 13:16:22 | 显示全部楼层
实际上 _FileListToArray 已经很高效了...舍近求远
Hen5ei 发表于 2011-2-3 21:59


但是如何跳过目录呢
发表于 2011-2-4 18:08:14 | 显示全部楼层
但是如何跳过目录呢
touch_xu 发表于 2011-2-4 13:16



    修改第二个可选参数

[可选参数]指定是否返回文件或文件夹;或者两者都返回:
设为 0 (默认) 返回文件和文件夹.
设为 1 只返回文件
设为 2 只返回文件夹
 楼主| 发表于 2011-2-4 23:56:43 | 显示全部楼层
本帖最后由 touch_xu 于 2011-2-5 00:16 编辑
修改第二个可选参数
Hen5ei 发表于 2011-2-4 18:08



    返回文件夹后还要再一次的对返回目录_进行FileListToArray 不是很麻烦吗,关键是有很多子目录,我只是很想找一种解决问题的方法,问题是可以解决的,但是我想一定有人能找到便捷的方法,谢谢了
发表于 2011-2-5 17:54:17 | 显示全部楼层
返回文件夹后还要再一次的对返回目录_进行FileListToArray 不是很麻烦吗,关键是有很多子目录,我 ...
touch_xu 发表于 2011-2-4 23:56



    那就遍历文件... 麻烦的事情就交给电脑做好了.你就坐享其成吧
发表于 2011-2-5 20:13:38 | 显示全部楼层
就一个遍历就OK了啊。个人觉得这个函数还是挺有用的。在这个函数基础上,还可以写不少自己想要的函数。
发表于 2011-2-12 14:58:00 | 显示全部楼层
好像楼主求过这个问题啊,还没有解决?
翻箱倒柜找出当时的代码出来,再给出来.
#include <array.au3>
$searchdir1 = "c:\windows"
Local $flag='*.dll'
Local $flag1 = "c:\windows\system", $flag2 = 'c:\windows\system32'
Local $lines, $direct, $array
 
_filelist($searchdir1, $flag,$flag1, $flag2);_filelist('搜索目录','要搜索的扩展名','排除目录1','排除目录2','排除目录3','排除目录4')
 
$a = StringSplit(StringTrimRight($lines,1), '|')
_ArrayDisplay($a)
 
Func _filelist($searchdir, $flag, $es1 = '', $es2 = '', $es3 = '',$es4='')
 
    $search = FileFindFirstFile($searchdir & "\*")
    If $search = -1 Then Return -1
    While 1
        $File = FileFindNextFile($search)
        If @error Then
            FileClose($search)
            Return
        ElseIf $File = "." Or $File = ".." Then
            ContinueLoop
        ElseIf StringInStr(FileGetAttrib($searchdir & "\" & $File), "D") Then ;And $searchdir & "\" & $File <> $flag Then
            Select
                Case $searchdir & "\" & $File = $es1
                    ContinueLoop
                Case $searchdir & "\" & $File = $es2
                    ContinueLoop
                Case $searchdir & "\" & $File = $es3
                    ContinueLoop
                Case $searchdir & "\" & $File = $es4
                    ContinueLoop
                Case Else
                    _filelist($searchdir & "\" & $File, $flag, $es1 = '', $es2 = '', $es3 = '',$es4)
                    ContinueLoop
            EndSelect
        EndIf
        If StringRight($searchdir & "\" & $File,4)=StringRight($flag,4) Then
            $lines &= $searchdir & "\" & $File & "|"
            $array = StringSplit(StringTrimRight($lines, 1), '|')
        EndIf
    WEnd
    Return $array
EndFunc   ;==>_filelist
 楼主| 发表于 2011-2-24 05:14:14 | 显示全部楼层
再次谢谢3mile 已经可以用
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-20 23:56 , Processed in 0.080734 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表