不点饣 发表于 2015-12-30 08:58:44

求大神帮忙优化代码!

1.想请大神帮忙优化FindFiles("c:","find*.*"),实现全盘搜索要找的文件!我这样写太繁琐了。
2.在本代码中加入获取本机 computerneme , username , date 一起写入到result.txt

感谢!#include <Array.au3>
#Include <File.au3>

Local $FileNumber = 0;记录数组维数,全局变量
Local $FileArray;返回的文件名主数组(全路径),全局变量
Local $result = "D:\result.txt"

FindFiles("c:","find*.*");这里改为你自己要遍历的文件夹
FindFiles("c:","auto*.*")                                                
FindFiles("d:","find*.*")
FindFiles("d:","auto*.*")
FindFiles("e:","find*.*")
FindFiles("e:","auto*.*")

;$FileArray = $FileNumber
;_ArrayDisplay($FileArray, "Pictures");调用“Array.au3”的子函数函数,显示整个数组信息
For $i = 1 To $FileNumber
        FileWriteLine($result, $FileArray[$i])
Next

Func FindFiles($path,$filelx)
Local $filelist
Local $folders
Local $i,$j,$newpath
$filelist = _FileListToArray ($path,$filelx,1)
if not @error then
if $filelist>0 Then
   for $i=1 to $filelist
    $FileNumber = $FileNumber + 1
    ReDim $FileArray   
    $FileArray[$FileNumber] = $path & "\" & $filelist[$i]
   Next
EndIf
EndIf
$folders = _FileListToArray ($path,"*",2)
if Not @error Then
   If $folders > 0 Then
    For $j=1 to $folders
   $newpath = $path & "\" & $folders[$j]
   FindFiles($newpath,$filelx)
    Next
   EndIf
EndIf
EndFunc

luren666 发表于 2015-12-30 15:35:58

全盘搜索本来就是很慢的,这个是没办法的。下面这个代码您可以试一下能不能符合您的要求,因为不能支持通配符,所以增加了匹配模式。Global $result = FileOpen("D:\result.txt",2+8)

FindFile("c:","find",1) ;;匹配模式 1左,2右,3任意,4精确
FindFile("c:","1.tmp",2) ;;匹配模式 1左,2右,3任意,4精确
FindFile("c:","rundll",3) ;;匹配模式 1左,2右,3任意,4精确

FileClose($result)

Func FindFile($sDir,$met,$mode)
        Local $hSearch = FileFindFirstFile($sDir & "\*.*")
        If $hSearch = -1 Then Return
        While 1
                Local $sFile = FileFindNextFile($hSearch)
                If @error Then
                        ExitLoop
                ElseIf @extended Then
                        FindFile($sDir & "\" & $sFile , $met,$mode)
                Else
                        Switch $mode
                                Case 1
                                        If StringLeft($sFile,StringLen($met)) <> $met Then ContinueLoop
                                Case 2
                                        If StringRight($sFile,StringLen($met)) <> $met Then ContinueLoop
                                Case 3
                                        If Not StringInStr($sFile,$met) Then ContinueLoop
                                Case 4
                                        If $sFile <> $met Then ContinueLoop
                        EndSwitch
                        FileWriteLine($result,$sDir & "\" & $sFile)
                EndIf
        WEnd
        ; 关闭搜索句柄
        FileClose($hSearch)
EndFunc

luren666 发表于 2015-12-30 15:47:47

第二个问题,直接在开始搜索之前加入下面代码就可以了。FileWriteLine($result,@ComputerName)
FileWriteLine($result,@UserName)

fuldho 发表于 2015-12-30 16:25:41

$sDir = FindAllFile("c:")
Func FindAllFile($sDir)
    Local $hSearch = FileFindFirstFile($sDir & "\*.*")
    If $hSearch = -1 Then Return
    While 1
      Local $sFile = FileFindNextFile($hSearch)
      If @error Then ExitLoop
      
      If @extended Then
            FindAllFile($sDir & "\" & $sFile)
            ContinueLoop
      EndIf
      If StringLeft($sFile,4)= "find" ThenFileWriteLine("d:\result.txt",$sDir &"\" & $sFile)
      
    WEnd
    FileClose($hSearch)
EndFunc

不点饣 发表于 2015-12-30 17:02:10

谢谢各位,学习到不少东西!我也把我完善的贴出来! 加了连接到sql

望大家指正 能不能更简洁!#include <Array.au3>
#Include <File.au3>
#include <Date.au3>

Local $FileNumber = 0;记录数组维数,全局变量
Local $FileArray;返回的文件名主数组(全路径),全局变量
Local $result = ("d:\Program Files\111.txt")
Local $PC = @ComputerName
Local $UN = @UserName
Local $Date = _Now()

;Local $Drive = DriveGetDrive("All")
Local $Drive=["C:","D:","E:","F:","G:","J:"]
Local $Pattern = ["a.exe","auto*","cad*","Key*","ak*"]

If Not @error Then
        For $m=0 To 5
                For $n=0 To 4
                        FindFiles($Drive[$m],$Pattern[$n])
                Next
                       
        Next
EndIf


For $i = 1 To $FileNumber
       
        FileWriteLine($result, $FileArray[$i])
Next

Func FindFiles($path,$filelx)
Local $filelist
Local $folders
Local $i,$j,$newpath

$filelist = _FileListToArray ($path,$filelx,1)
if not @error then
if $filelist>0 Then
   for $i=1 to $filelist
    $FileNumber = $FileNumber + 1
    ReDim $FileArray   
    $FileArray[$FileNumber] = $Date & " " & $UN & " " & $PC & " " & $path & "\" & $filelist[$i]
   Next
EndIf
EndIf
$folders = _FileListToArray ($path,"*",2)
if Not @error Then
   If $folders > 0 Then
    For $j=1 to $folders
   $newpath = $path & "\" & $folders[$j]
   FindFiles($newpath,$filelx)
    Next
   EndIf
EndIf
EndFunc

;belos is for define a function to save data to database.
Global $Server = "192.168.1.*" ;SQL主机名称
Global $ID = "sa" ; 登入数据库主机的账号一般都会用sa
Global $pw = "12345****" ;登入数据库主机的密码
Global $DataName = "Data" ;数据库名称

$conn = ObjCreate("ADODB.Connection")
$RS = ObjCreate("ADODB.Recordset")
$conn.Open("driver={SQL Server};server=" & $Server & ";uid=" & $ID & ";pwd=" & $pw & ";database=" & $DataName)
;If @error Then Exit
If Not @error Then
      MsgBox(0, '', '连接数据库成功')
Else
      MsgBox(0, '', '连接数据库失败')
      Exit
EndIf

$RS.ActiveConnection = $conn

不点饣 发表于 2015-12-30 17:03:44

回复 3# luren666
学习了!

luren666 发表于 2015-12-30 21:38:16

本帖最后由 luren666 于 2015-12-30 21:42 编辑

估计这样会快一些,不需要每次都遍历一次磁盘文件,这样会在找到一个文件后就会循环判断是否符合其中一个条件。其实可以不用每次都传二维数组到函数,定义一个全局二维数组,然后在函数内判断就可以,不过貌似传参数的话,可以实现每个磁盘查找不同的文件,多定义一个二维数组,然后不同的磁盘传不同的数组就可以了,所以我就保留了下来。
Global $result = FileOpen("D:\result.txt",2+8)
Local $Drive=["D:","E:"]
;;二维数组存放【文件,配匹模式】,匹配模式 1左,2右,3任意,4精确
Local $Pattern = [,["a.exe",2],["auto",1],["cad",1],["Key",1],["ak",1]]

For $s = 0 To UBound($Drive) - 1
        FindFile($Drive[$s],$Pattern)
Next


FileClose($result)

Func FindFile($sDir,ByRef $Pattern)
      Local $hSearch = FileFindFirstFile($sDir & "\*.*")
      If $hSearch = -1 Then Return
      While 1
                Local $sFile = FileFindNextFile($hSearch)
                If @error Then
                  ExitLoop
                ElseIf @extended Then
                                        FindFile($sDir & "\" & $sFile,$Pattern)
                                Else
                                        For $x = 1 To $Pattern
                                                Switch $Pattern[$x]
                                                                Case 1
                                                                        If StringLeft($sFile,StringLen($Pattern[$x])) = $Pattern[$x] Then FileWriteLine($result,$sDir & "\" & $sFile)
                                                                Case 2
                                                                        If StringRight($sFile,StringLen($Pattern[$x])) = $Pattern[$x] Then FileWriteLine($result,$sDir & "\" & $sFile)
                                                                Case 3
                                                                        If StringInStr($sFile,$Pattern[$x]) Then FileWriteLine($result,$sDir & "\" & $sFile)
                                                                Case 4
                                                                        If $sFile = $Pattern[$x] Then FileWriteLine($result,$sDir & "\" & $sFile)
                                                EndSwitch
                                        Next
                EndIf
      WEnd
      ; 关闭搜索句柄
      FileClose($hSearch)
EndFunc

luren666 发表于 2015-12-30 22:32:20

本帖最后由 luren666 于 2015-12-30 22:37 编辑

按照你的输出结果的模式修改了一下,在我的电脑上实测了一下,因我的电脑里面存的文件较多,所以只遍历D和E盘,实测需要4.2秒左右,您的代码是12.3秒左右。Global $result = FileOpen("D:\result.txt",2+8)
Local $Drive=["D:","E:"]
;;二维数组存放【文件,配匹模式】,匹配模式 1左,2右,3任意,4精确
Global $Pattern = [["a.exe",4],["auto",1],["cad",1],["Key",1],["ak",1]]
Local $DateUserComputer = @YEAR & "\" & @MON & "\" & @MDAY & " " & @HOUR & ":" & @MIN & ":"& @SEC & " " & @UserName & " " & @ComputerName & " "
For $s = 0 To UBound($Drive) - 1
        FindFile($Drive[$s])
Next

FileClose($result)

Func FindFile($sDir)
      Local $hSearch = FileFindFirstFile($sDir & "\*.*")
      If $hSearch = -1 Then Return
      While 1
                Local $sFile = FileFindNextFile($hSearch)
                If @error Then
                  ExitLoop
                ElseIf @extended Then
                                        FindFile($sDir & "\" & $sFile)
                                Else
                                        For $x = 0 To UBound($Pattern) - 1
                                                Switch $Pattern[$x]
                                                                Case 1
                                                                        If StringLeft($sFile,StringLen($Pattern[$x])) = $Pattern[$x] Then FileWriteLine($result, $DateUserComputer & $sDir & "\" & $sFile )
                                                                Case 2
                                                                        If StringRight($sFile,StringLen($Pattern[$x])) = $Pattern[$x] Then FileWriteLine($result,$DateUserComputer & $sDir & "\" & $sFile)
                                                                Case 3
                                                                        If StringInStr($sFile,$Pattern[$x]) Then FileWriteLine($result,$DateUserComputer & $sDir & "\" & $sFile)
                                                                Case 4
                                                                        If $sFile = $Pattern[$x] Then FileWriteLine($result,$DateUserComputer & $sDir & "\" & $sFile)
                                                EndSwitch
                                        Next
                EndIf
      WEnd
      ; 关闭搜索句柄
      FileClose($hSearch)
EndFunc另外,发现一个奇怪的现像,我的电脑里面有一个文件路径是:E:\软件\图标ICON\图标藏经阁\ICONSMAX9\Function_Icon_Set\camera_noflash_delete_48.png
你的脚本输出结果里面有这一行,而我的脚本里没有,其它行的结果除了顺序不同外全部都一样,就是有这一行的误差。不知道是什么原因,怎么会出现这个奇怪的现像,不明白是怎么匹配到这个文件名的。

ddrs 发表于 2016-1-2 01:22:18

值得研究,不错的贴。。。。

kadingxiaodi 发表于 2016-1-5 10:51:44

学习一下{:face (280):}
页: [1]
查看完整版本: 求大神帮忙优化代码!