找回密码
 加入
搜索
楼主: xtanxin

求一个遍历目录然后将文件路径写入数组的源码!是将全路径文件名写入数组

 火.. [复制链接]
发表于 2010-1-9 14:05:07 | 显示全部楼层
学习一下,不错。
发表于 2010-1-10 14:37:12 | 显示全部楼层
阿福一口气写了这么多函数,高
 楼主| 发表于 2010-1-10 18:23:44 | 显示全部楼层
感谢各位了,afan 顽固不化 C.L 阿福 本来昨天就写好感激之言,结果其他事情忙起来,没有点击发表,今天再谢谢大家一直关注了.
c.l的测试了也可以,阿福的考虑更周全,为以后学习借鉴提供了宝贵的资料.
看过很多编程入门的书,仅仅是有点点的兴趣,没有深入学习应用过.一直忽略的是正则表达式.这次应用体会比较深.
很有用.
发表于 2010-1-14 17:45:49 | 显示全部楼层
本帖最后由 supersp 于 2010-1-14 18:43 编辑

func _DirectorFind()
    Local $cmd = "for /f %i in ('dir /b /a:-d') do @echo %~fi"
    Local $foo = Run(@ComSpec & ' /c '&$cmd, "", @SW_HIDE, $STDOUT_CHILD)
    Local $line,$cow
    While 1
          $line &= StdoutRead($foo) ;读取CMD STDOUT
          If @error Then ExitLoop
    WEnd
    $cow = StringSplit($line, @CRLF, 1) ;按行分解到数组,$cow[0] 返回数组个数
    return $cow
endfunc


其实使用命令行现成工具,可以省却非常多的代码
比如稍微改动一下,加入参数, 让函数只搜索指定后缀文件,而且是多种,效果试试 dir *.xls *.doc 就知道了
另外,因为DIR本身命令的强大,可以根据要求排序文件,根据属性搜索,根据文件所有者搜索, 可以遍历子目录,可以得到所有合乎要求文件组的总字节,
只输出目录名,再加上cmd里的for,findstr ,sort ,参数扩展(如代码中的 %i 使用%~fi 就可以得到包含路径的文件名),等等复杂的要求。
发表于 2010-1-14 19:09:08 | 显示全部楼层
才发现,前面有人用dir /s 了
不过其实在输出结果前,可以用CMD命令来预先处理结果,可以减少非常多的数组操作,速度问题没验证过,但应该不慢。

另外,遍历子目录 可以使用 for /r %i in (*)do @echo %~fi 得到所有的包含路径的文件名,测试C盘搜索文件也非常快。()内可以使用*.xls 等通配符,使用(.)得到子目录而不包含文件。
可以使用 for /r %i in (*)do @echo %~fi $ %~ti $ %~zi 等等组合来得到文件的各种属性并使用自定义的分隔符来输出在一行

在读入数组后,进行处理时,使用字符串分割即可,无需调用其他文件处理函数来做了。

可别小瞧了命令行的强大..特别是处理文件,文本,字符的时侯..
发表于 2011-3-13 17:40:07 | 显示全部楼层
解决了,楼主
发表于 2011-3-13 17:40:54 | 显示全部楼层
多亏了阿福
发表于 2011-8-13 23:20:14 | 显示全部楼层
不知道怎么用
发表于 2011-8-14 00:44:57 | 显示全部楼层
学习下,谢谢
发表于 2012-1-5 09:24:01 | 显示全部楼层
来学习了,
发表于 2013-6-29 17:22:36 | 显示全部楼层
感谢分享,学习了
发表于 2014-9-3 20:03:19 | 显示全部楼层
本帖最后由 dunphy 于 2014-9-3 20:28 编辑

回复 1# xtanxin


    不用递归,用File System Obj方法 ,见贴子http://www.autoitx.com/forum.php ... p;extra=&page=1  

我以前用过这个做对比更新,查找WINDOWS目录下(包括子目录)下的所有文件,挺快的. 另备注已给你标出,帮助你学习。
#include <Array.au3>
Local $filefolder = FileSelectFolder("", "") ;选择一个文件,得到一个带路径的文件名字符串

Local $T = TimerInit()  ;开始计时
Local $sFiles = _FileListEx($filefolder)   ;列出目录下所有文件,以" |"分开
Select
        Case @error                                     ;如果出错
                ConsoleWrite("原始文件夹不存在" & @CRLF)   ;写入数据流原始文件不存在。
        Case $sFiles                                    ;如果是带路径的文件名字符串


;StringSplit ( "字符串", "分隔符" [, 标志 = 0] )      ;拆分字符串为若干子串.
; 标志 $STR_NOCOUNT (2) = 禁用返回表示元素数量的第一个元素 - 方便使用基于 0 开始的数组.(此时的数组大小由 UBound() 函数检测).
;常量定义在 StringConstants.au3

                Local $a_FileList = StringSplit($sFiles, "|")  ;返回拆分了的子串符串以数组表示,第一个元素里含折分的子串总数
;TimerDiff ( 句柄 )
;句柄 之前调用 TimerInit() 返回的句柄.
;返回当前与之前调用 TimerInit() 之间的时间间隔(毫秒).
                ConsoleWrite("耗时:" & TimerDiff($T) / 1000 & "秒,共有文件数:" & $a_FileList[0] & @CRLF);耗时:1.04020835328356秒,共有文件数:9250

                _ArrayDisplay($a_FileList, "$a_FileList")
                ;$a_FileList[1..n]: 带路径的文件名
        Case Else ;$sFiles=""                    ;如果什么都没有,写入数据流,没有找到文件
                ConsoleWrite("没有找到文件" & @CRLF)
EndSelect



Func _FileListEx($filefolder)

   ; local $ml=FileGetAttrib($filefolder)
   ; MsgBox(0,"文件属性代码为",$ml)
        ;FileGetAttrib($filefolder) 返回选择文件的属性的代码字符串.

;        String()返回的字符串可能包含 "RASHNDOCT" 字符的组合:
;"R" = 只读文件
;"A" = 存档文件
;"S" = 系统文件
;"H" = 隐藏文件
;"N" = 普通文件
;"D" = 目录文件
;"O" = 脱机文件
;"C" = 压缩文件 (NTFS 压缩, 并非 ZIP/RAR 压缩)
;"T" = 临时文件

        ;StringInStr ( "字符串", "子字符串" [, 区分大小写 = 0 [, 出现位置 = 1 [, 开始 = 1 [, 数量]]]] )    返回子串在字符串中的开始位置. 返回 0, 未发现匹配子串.
        ;SetError ( 代码 [, 扩展值 = 0 [, 返回值 ]] )        设置宏 @error 的值(可选设置 @extended).  @error 限定值在 -2147483648 到 2147483647 之间.
        If StringInStr(FileGetAttrib($filefolder), "D") = 0 Then Return SetError(1, 0, "")  ;检查选择的文件夹属性的代码字符串是否为包含了“d”即是否为目录文件,并返回开始位置,
;        若返回值为0,则设置@ERROR的值为0
;   MsgBox(0,"@ERROR",@ERROR)
 ;  MsgBox(0,"@extended",@extended)

  ;ObjCreate ( "类名称" [, "服务器名称" [,"用户名", ["密码"]]] )   对象的类名称, 格式如下: "appname.objectype"(程序名.对象类型)
        Local $oFSO = ObjCreate("Scripting.FileSystemObject")        ;创建$OFSO对像
        Local $objDir                                         ;定义OBj对像目录函数

        Local $aDir = StringSplit($filefolder, "|", 2)       ;返回所选文件夹目录下所有的含目录的文件名的数组,并禁用第一个元素 ,方便使用基于 0 开始的数组

        Local $iCnt = 0              ;设置计数为0
        Local $sFiles = ""           ;定义一个收到的文件参数目录为空
        Do
                $objDir = $oFSO.GetFolder($aDir[$iCnt])     ;获取文件目录
                For $aItem In $objDir.SubFolders                                                       ;获取文件名
                        ;扩展应用改下这句, 如指定文件夹 If StringInStr($aItem.Name, "XXX") Then
                        $filefolder &= "|" & $aItem.Path


                        ;文件夹层数可以通过 StringReplace($aItem.Path, "", "", 0, 1)的@extended值来判断
                Next
                ;如果仅找文件夹,不找文件,$sFiles的语句都不用,最后是 Return $filefolder
                For $aItem In $objDir.Files
                        ;扩展应用改下面这句
                        $sFiles &= $aItem.Path & "|"
                        ;例如要找文件名中包含"kb"(不分大小写),改为: if StringInStr($aItem.Name, "kb") Then $sFiles &= $aItem.Path & "|"
                        ;其他应用请参照上例修改: $aItem.XXX
                        ;Attributes        设置或返回文件或文件夹的属性
                        ;DateCreated   返回指定的文件或文件夹的创建日期和时间。只读
                        ;DateLastAccessed 返回指定的文件或文件夹的上次访问日期(和时间)。只读
                        ;DateLastModified 返回指定的文件或文件夹的上次修改日期和时间。只读
                        ;ShortName   返回按照早期8.3文件命名约定转换的短文件名
                        ;ShortPath   返回按照早期8.3命名约定转换的短路径名
                        ;Size    对于文件返回指定文件的字节数;对于文件夹,返回文件夹所有的文件夹和子文件夹的字节数
                        ;Type    返回文件或文件夹的类型信息
                Next
                $iCnt += 1
                If UBound($aDir) <= $iCnt Then $aDir = StringSplit($filefolder, "|", 2)
        Until UBound($aDir) <= $iCnt
        If $sFiles Then $sFiles = StringTrimRight($sFiles, 1);去掉最右边"|"
        Return $sFiles
EndFunc   ;==>_FileListEx
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-16 12:12 , Processed in 0.067606 second(s), 13 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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