Показать полную графическую версию : [решено] Рекурсивный поиск файла
Поиск файла выполняется при помощи функции, и выполняется очень долго. Возможно ли реализовать поиск файла в каталогах и подкаталогах другим способом - более быстрым?
Func _FindFiles($sRoot, $sFile)
Local $FileList
$FileList = _FileListToArray($sRoot, $sFile, 1)
If Not @error Then
For $i = 1 To $FileList[0]
$filename2 = StringMid($Filelist[$i],StringInStr($Filelist[$i],"\",0,-1)+ 1)
MsgBox(64,"",$filename2)
Next
EndIf
$FileList = _FileListToArray($sRoot, '*', 2)
If Not @error Then
For $i = 1 To $FileList[0]
_FindFiles($sRoot & '\' & $FileList[$i], $sFile)
Next
EndIf
EndFunf
попробовал такой поиск но по скорости поиска почти одинаковы
Func FileSearch($sPath, $sFileSrh) ;путь к каталогу и имя файла
Local $sFile, $Search, $sRes = ""
While 1
$Search = FileFindFirstFile($sPath & "\" & $sFileSrh)
If @error Then Return ""
While 1
$sFile = FileFindNextFile($Search)
If @error Then ExitLoop
$sFile = $sPath & "\" & $sFile
If StringInStr(FileGetAttrib($sFile), "D") > 0 Then ContinueLoop
$sRes = $sFile
MsgBox(64,"",$sRes)
WEnd
FileClose($Search)
$Search = FileFindFirstFile($sPath & "\*.*")
If @error Then ExitLoop
While 1
$sFile = FileFindNextFile($Search)
If @error Then ExitLoop
$sFile = $sPath & "\" & $sFile
If StringInStr(FileGetAttrib($sFile), "D") = 0 Then ContinueLoop
$sRes = FileSearch($sFile, $sFileSrh)
If $sRes <> "" Then ExitLoop 2
WEnd
ExitLoop
WEnd
FileClose($Search)
Return $sRes
EndFunc
файлов около 5000 и больше в 50 папках
Можно ли организовать поиск файла через WinAPI?
Мне понадобилось запустить все регфайлы в @ScriptDir & "\*\*\*....... рекурсивноооо
Как всегда ничего приличного не нашёл и был очень зол :)
Заодно поглядел что есть из файнд файл и примеров гугл, и там тоже громадные скрипты для такой простой задачи. :\
Хотя понмиаю, это у меня прстая задача, конечно там видимо что-то более серьёзное...
??
#include <Array.au3>
$aReturn = _FileSearch(@WindowsDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@WindowsDir), "File\....$", 0)
_ArrayDisplay($aReturn)
Func (http://www.autoitscript.com/autoit3/docs/keywords.htm#Func) _FileSearch($sPath, $sRegExp_FileMask, $iCaseSense=0)
Local (http://www.autoitscript.com/autoit3/docs/keywords.htm#Local) $iPID, $sStdOutRead, $aRet, $sFindStr, $sCaseStr
If (http://www.autoitscript.com/autoit3/docs/keywords.htm#If) Not (http://www.autoitscript.com/autoit3/docs/keywords.htm#Not) $iCaseSense Then (http://www.autoitscript.com/autoit3/docs/keywords.htm#Then) $sCaseStr = ' /I'
$sFindStr = 'Dir "' & $sPath & '" /S /B | FindStr' & $sCaseStr & ' /R "' & $sRegExp_FileMask & '"'
$iPID = Run (http://www.autoitscript.com/autoit3/docs/functions/Run.htm)(@ComSpec (http://www.autoitscript.com/autoit3/docs/macros.htm#@ComSpec) & ' /C ' & $sFindStr, @SystemDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@SystemDir), @SW_HIDE (http://www.autoitscript.com/autoit3/docs/macros.htm#@SW_HIDE), 2)
While (http://www.autoitscript.com/autoit3/docs/keywords.htm#While) 1
$sStdOutRead &= StdoutRead (http://www.autoitscript.com/autoit3/docs/functions/StdoutRead.htm)($iPID)
If (http://www.autoitscript.com/autoit3/docs/keywords.htm#If) @error (http://www.autoitscript.com/autoit3/docs/macros.htm#@error) <> 0 Then (http://www.autoitscript.com/autoit3/docs/keywords.htm#Then) ExitLoop (http://www.autoitscript.com/autoit3/docs/keywords.htm#ExitLoop)
WEnd (http://www.autoitscript.com/autoit3/docs/keywords.htm#WEnd)
$aRet = StringSplit (http://www.autoitscript.com/autoit3/docs/functions/StringSplit.htm)(StringStripCR (http://www.autoitscript.com/autoit3/docs/functions/StringStripCR.htm)(StringStripWS (http://www.autoitscript.com/autoit3/docs/functions/StringStripWS.htm)($sStdOutRead, 3)), @LF (http://www.autoitscript.com/autoit3/docs/macros.htm#@LF))
Return (http://www.autoitscript.com/autoit3/docs/keywords.htm#Return) SetError (http://www.autoitscript.com/autoit3/docs/functions/SetError.htm)(@error (http://www.autoitscript.com/autoit3/docs/macros.htm#@error), 0, $aRet)
EndFunc (http://www.autoitscript.com/autoit3/docs/keywords.htm#EndFunc)
Можно ли организовать поиск файла через WinAPI »
Врядли оно будет быстрее (в AutoIt).
Такс, коллекция скриптов с рекурсивным поиском пополняется. первыми двумя способами файл ищется 14-16 сек, последним способом 49-52 о_О
первыми двумя способами файл ищется 14-16 сек, последним способом 49-52 »
Ну так в чём проблема, первый способ значит быстрее ;).
P.S
А имя файла точное, или нужен поиск по маске? Возможно замедление из за поиска используя регулярные выражения.
имя файла задаю полное, файл в папках существует такой только один. виндовым поиском ищет до 10 сек
забросил поиск решения об быстром поиске файла. Подскажите как остановить функцию поиска файла после того как файл найден, потому как при нахождении файла функция продолжает сканировать остальные папки.
Подскажите как остановить функцию поиска файла после того как файл найден, потому как при нахождении файла функция продолжает сканировать остальные папки. »
#Include <File.au3>
Func _FindFiles($sRoot, $sFile)
Local $FileList
$FileList = _FileListToArray($sRoot, $sFile, 1)
If Not @error Then
For $i = 1 To $FileList[0]
$filename2 = StringMid($FileList[$i], StringInStr($FileList[$i], "\", 0, -1) + 1)
MsgBox(64, "", $filename2)
Return 1
Next
EndIf
$FileList = _FileListToArray($sRoot, '*', 2)
If Not @error Then
For $i = 1 To $FileList[0]
If _FindFiles($sRoot & '\' & $FileList[$i], $sFile) Then
Return 1
EndIf
Next
EndIf
Return 0
EndFunc ;==>_FindFiles
_FindFiles('C:\', '*.au3')
коллекция скриптов с рекурсивным поиском пополняется »
тогда до кучи, вариант через WMI: :)
#include <array.au3>
$a = _FileFindLike("spuninst.exe", "C:\\WINDOWS\\$")
_ArrayDisplay($a)
Func _FileFindLike($strRight, $strLeft = @HomeDrive, $sComputer = ".")
Local $arrRight= StringRegExp($strRight, "^(.*?(?:\.([^.\\]*))?)$", 3)
If Not(IsArray($arrRight)) Then Return SetError(1, 1)
Local $arrLeft = StringRegExp($strLeft , "^([A-Za-z]:)(.*)", 3)
If Not(IsArray($arrLeft)) Then Return SetError(1, 2)
Local $strDrive = $arrLeft[0], $strPath = $arrLeft[1]
Local $strName = $arrRight[0], $strExtn = ""
If UBound($arrRight)=2 Then $strExtn = $arrRight[1]
Local $objWMI = ObjGet("winmgmts:\\" & $sComputer & "\root\cimv2")
If Not(IsObj($objWMI)) Then Return SetError(2, 1, "")
Local $strQuery = 'SELECT * FROM CIM_DataFile WHERE Drive="'& $strDrive & _
'" AND Extension="'& $strExtn &'" AND Path LIKE "'& $strPath & _
'%" AND Name LIKE "%'& $strName &'"'
Local $arrRes[1] = [0], $colItems = $objWMI.ExecQuery($strQuery)
If Not(IsObj($colItems)) Then Return SetError(2, 2, "")
For $objItem In $colItems
$arrRes[0]+=1
ReDim $arrRes[$arrRes[0]+1]
$arrRes[$arrRes[0]]=$objItem.Path
Next
Return $arrRes
EndFunc
Можно ли организовать поиск файла через WinAPI
Врядли оно будет быстрее (в AutoIt).
В WinAPI есть продвинутая функция FindFirstFileEx(работает только в win2000 и выше) - вот ссылка (http://msdn.microsoft.com/en-us/library/aa364419(VS.85).aspx) на мануал
Можно значительно ускорить поиск файлов, если избавиться от рекурсии.
Много времени уходит на многочисленный вызов функции.
Можно значительно ускорить поиск файлов, если избавиться от рекурсии. »
Вот так:
$sFile = _FileSearch(@DesktopDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@DesktopDir), "test.txt")
MsgBox (http://www.autoitscript.com/autoit3/docs/functions/MsgBox.htm)(64, 'Title', $sFile)
Func (http://www.autoitscript.com/autoit3/docs/keywords.htm#Func) _FileSearch($sPath, $sMask="*")
If (http://www.autoitscript.com/autoit3/docs/keywords.htm#If) Not (http://www.autoitscript.com/autoit3/docs/keywords.htm#Not) StringInStr (http://www.autoitscript.com/autoit3/docs/functions/StringInStr.htm)(FileGetAttrib (http://www.autoitscript.com/autoit3/docs/functions/FileGetAttrib.htm)($sPath & "\"), "D") Then (http://www.autoitscript.com/autoit3/docs/keywords.htm#Then) Return (http://www.autoitscript.com/autoit3/docs/keywords.htm#Return) SetError (http://www.autoitscript.com/autoit3/docs/functions/SetError.htm)(1, 0, 0)
Local (http://www.autoitscript.com/autoit3/docs/keywords.htm#Local) $hSearch, $sFindNext, $sFilePath, $iPathIsFolder, $i = 0, $sRet = -1
Local (http://www.autoitscript.com/autoit3/docs/keywords.htm#Local) $sRegExpFilter = StringReplace (http://www.autoitscript.com/autoit3/docs/functions/StringReplace.htm)(StringReplace (http://www.autoitscript.com/autoit3/docs/functions/StringReplace.htm)(StringReplace (http://www.autoitscript.com/autoit3/docs/functions/StringReplace.htm)($sMask, ".", "\."), "*", ".*"), "?", ".")
Local (http://www.autoitscript.com/autoit3/docs/keywords.htm#Local) $iMax_Ret_Paths = 10000
Local (http://www.autoitscript.com/autoit3/docs/keywords.htm#Local) $aPathesArr[$iMax_Ret_Paths+1] = [1, $sPath]
While (http://www.autoitscript.com/autoit3/docs/keywords.htm#While) $i < $aPathesArr[0]
$i += 1
$hSearch = FileFindFirstFile (http://www.autoitscript.com/autoit3/docs/functions/FileFindFirstFile.htm)($aPathesArr[$i] & "\*")
If (http://www.autoitscript.com/autoit3/docs/keywords.htm#If) $hSearch = -1 Then (http://www.autoitscript.com/autoit3/docs/keywords.htm#Then) ContinueLoop (http://www.autoitscript.com/autoit3/docs/keywords.htm#ContinueLoop)
While (http://www.autoitscript.com/autoit3/docs/keywords.htm#While) 1
$sFindNext = FileFindNextFile (http://www.autoitscript.com/autoit3/docs/functions/FileFindNextFile.htm)($hSearch)
If (http://www.autoitscript.com/autoit3/docs/keywords.htm#If) @error (http://www.autoitscript.com/autoit3/docs/macros.htm#@error) Then (http://www.autoitscript.com/autoit3/docs/keywords.htm#Then) ExitLoop (http://www.autoitscript.com/autoit3/docs/keywords.htm#ExitLoop)
$sFilePath = $aPathesArr[$i] & "\" & $sFindNext
$iPathIsFolder = StringInStr (http://www.autoitscript.com/autoit3/docs/functions/StringInStr.htm)(FileGetAttrib (http://www.autoitscript.com/autoit3/docs/functions/FileGetAttrib.htm)($sFilePath & "\"), "D")
If (http://www.autoitscript.com/autoit3/docs/keywords.htm#If) $iPathIsFolder Then (http://www.autoitscript.com/autoit3/docs/keywords.htm#Then)
If (http://www.autoitscript.com/autoit3/docs/keywords.htm#If) $aPathesArr[0] >= $iMax_Ret_Paths Then (http://www.autoitscript.com/autoit3/docs/keywords.htm#Then)
$iMax_Ret_Paths *= 2
ReDim (http://www.autoitscript.com/autoit3/docs/keywords.htm#ReDim) $aPathesArr[$iMax_Ret_Paths+1]
EndIf (http://www.autoitscript.com/autoit3/docs/keywords.htm#EndIf)
$aPathesArr[0] += 1
$aPathesArr[$aPathesArr[0]] = $sFilePath
ElseIf (http://www.autoitscript.com/autoit3/docs/keywords.htm#ElseIf) StringRegExp (http://www.autoitscript.com/autoit3/docs/functions/StringRegExp.htm)($sFindNext, "(?i)\A" & $sRegExpFilter & "\z") Then (http://www.autoitscript.com/autoit3/docs/keywords.htm#Then)
$sRet = $sFilePath
ExitLoop (http://www.autoitscript.com/autoit3/docs/keywords.htm#ExitLoop)
EndIf (http://www.autoitscript.com/autoit3/docs/keywords.htm#EndIf)
WEnd (http://www.autoitscript.com/autoit3/docs/keywords.htm#WEnd)
FileClose (http://www.autoitscript.com/autoit3/docs/functions/FileClose.htm)($hSearch)
If (http://www.autoitscript.com/autoit3/docs/keywords.htm#If) $sRet <> -1 Then (http://www.autoitscript.com/autoit3/docs/keywords.htm#Then) ExitLoop (http://www.autoitscript.com/autoit3/docs/keywords.htm#ExitLoop)
WEnd (http://www.autoitscript.com/autoit3/docs/keywords.htm#WEnd)
Return (http://www.autoitscript.com/autoit3/docs/keywords.htm#Return) SetError (http://www.autoitscript.com/autoit3/docs/functions/SetError.htm)(Number (http://www.autoitscript.com/autoit3/docs/functions/Number.htm)($sRet = -1), 0, $sRet)
EndFunc (http://www.autoitscript.com/autoit3/docs/keywords.htm#EndFunc)
Вот так: »
#Include <Array.au3>
$begin1 = TimerInit()
$sFile = FileList(@WindowsDir, "*.ini")
$dif1 = TimerDiff($begin1)
_ArrayDisplay($sFile,$dif1)
Func FileList($sPath, $inFilter = '*', $exFilter = '');$includeFilter='*.txt,*.htm' $excludeFilter='www,asp,desktop'
$sPath = StringRegExpReplace($sPath, '\\+$', '')
Local $aRetArray[1], $sFindNextFile, $sCurrentPath, $iFL
Global $FolderList[2]
$aRetArray[0] = 0
$FolderList[0] = 1
$FolderList[1] = $sPath
Local $sFindFirstFile = FileFindFirstFile($sPath & "\*")
If @error = 1 Then Return SetError(1, 0, -1)
#Region
If StringRight($inFilter, 1) = ',' Then $inFilter = StringTrimRight($inFilter, 1)
$inFilter = StringReplace($inFilter, '^', '\^')
$inFilter = StringReplace($inFilter, '.', '\.')
$inFilter = StringReplace($inFilter, '(', '\(')
$inFilter = StringReplace($inFilter, ')', '\)')
$inFilter = StringReplace($inFilter, '[', '\[')
$inFilter = StringReplace($inFilter, ']', '\]')
$inFilter = StringReplace($inFilter, '+', '\+')
$inFilter = StringReplace($inFilter, '$', '\$')
$inFilter = StringReplace($inFilter, '*', '.*')
$inFilter = '(?i)^' & StringReplace($inFilter, ',', '$|^') & '$'
If StringInStr($exFilter, ',') > 0 And $exFilter <> '' Then
If StringRight($exFilter, 1) = ',' Then $exFilter = StringTrimRight($exFilter, 1)
$exFilter = StringReplace($exFilter, ',', '|')
$exFilter = StringReplace($exFilter, '.', '\.')
$exFilter = StringReplace($exFilter, '(', '\(')
$exFilter = StringReplace($exFilter, ')', '\)')
$exFilter = StringReplace($exFilter, '[', '\[')
$exFilter = StringReplace($exFilter, ']', '\]')
$exFilter = StringReplace($exFilter, '+', '\+')
$exFilter = StringReplace($exFilter, '$', '\$')
$exFilter = '(?i)(' & StringReplace($exFilter, '^', '\^') & ')'
EndIf
#EndRegion
$iFL = 1
Do
$sFindFirstFile = FileFindFirstFile($FolderList[$iFL] & "\*")
If @error = 0 Then
While 1
$sFindNextFile = FileFindNextFile($sFindFirstFile)
If @error = 1 Then ExitLoop
$sCurrentPath = $FolderList[$iFL] & "\" & $sFindNextFile
If StringInStr(FileGetAttrib($sCurrentPath), "D") Then;папка
$FolderList[0] += 1
If UBound($FolderList) < $FolderList[0] + 1 Then ReDim $FolderList[$FolderList[0] + 1000]
$FolderList[$FolderList[0]] = $sCurrentPath
Else;файл
If StringRegExp($sFindNextFile, $inFilter) = 1 And ($exFilter = '' Or StringRegExp($sFindNextFile, $exFilter) = 0) Then
$aRetArray[0] += 1
If UBound($aRetArray) < $aRetArray[0] + 1 Then ReDim $aRetArray[$aRetArray[0] + 1000]
$aRetArray[$aRetArray[0]] = $sCurrentPath
EndIf
EndIf
WEnd
EndIf
FileClose($sFindFirstFile)
$iFL += 1
Until $iFL > $FolderList[0]
ReDim $aRetArray[$aRetArray[0] + 1]
ReDim $FolderList[$FolderList[0] + 1]
Return $aRetArray
EndFunc ;==>FileList
Этот скрипт осматривает папку WindowsDir в 6 раз быстрее, чем из предыдущего поста
Будте любезны зделайте мне этот пример по типам *.reg и с запуском $regfiles /s
И не ругайтесь, что я встреваю, но не понял что ищете все файлы ($includeFilter='*.txt,*.htm') чтоли? Зделайте по типам!
(GUI вывод мне не нужен...)
пример по типам *.reg »
$path = @ScriptDir
$sFile = FileList($path, "*.reg")
If $sFile[0]>0 Then
For $i=1 To $sFile[0]
Run('regedit /s "' & $sFile[$i] & '"')
Next
EndIf
функция FileList из моего предыдущего поста.
в переменной $path указать, где искать файлы.
Этот скрипт осматривает папку WindowsDir в 6 раз быстрее, чем из предыдущего поста »
А так:
#include <Array.au3>
$begin1 = TimerInit (http://www.autoitscript.com/autoit3/docs/functions/TimerInit.htm)()
$aReturn = _FileSearch(@WindowsDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@WindowsDir), "*.ini")
$dif1 = TimerDiff (http://www.autoitscript.com/autoit3/docs/functions/TimerDiff.htm)($begin1)
_ArrayDisplay($aReturn, Round (http://www.autoitscript.com/autoit3/docs/functions/Round.htm)($dif1, 2))
Func (http://www.autoitscript.com/autoit3/docs/keywords.htm#Func) _FileSearch($sPath, $sFileMask)
Local (http://www.autoitscript.com/autoit3/docs/keywords.htm#Local) $iPID, $sStdOutRead, $aRet
$iPID = Run (http://www.autoitscript.com/autoit3/docs/functions/Run.htm)(@ComSpec (http://www.autoitscript.com/autoit3/docs/macros.htm#@ComSpec) & ' /C Dir "' & $sPath & '\' & $sFileMask & '" /S /B /A RASH', @SystemDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@SystemDir), @SW_HIDE (http://www.autoitscript.com/autoit3/docs/macros.htm#@SW_HIDE), 6)
While (http://www.autoitscript.com/autoit3/docs/keywords.htm#While) 1
$sStdOutRead &= StdoutRead (http://www.autoitscript.com/autoit3/docs/functions/StdoutRead.htm)($iPID)
If (http://www.autoitscript.com/autoit3/docs/keywords.htm#If) @error (http://www.autoitscript.com/autoit3/docs/macros.htm#@error) <> 0 Then (http://www.autoitscript.com/autoit3/docs/keywords.htm#Then) ExitLoop (http://www.autoitscript.com/autoit3/docs/keywords.htm#ExitLoop)
WEnd (http://www.autoitscript.com/autoit3/docs/keywords.htm#WEnd)
$aRet = StringSplit (http://www.autoitscript.com/autoit3/docs/functions/StringSplit.htm)(StringStripCR (http://www.autoitscript.com/autoit3/docs/functions/StringStripCR.htm)(StringStripWS (http://www.autoitscript.com/autoit3/docs/functions/StringStripWS.htm)($sStdOutRead, 3)), @LF (http://www.autoitscript.com/autoit3/docs/macros.htm#@LF))
Return (http://www.autoitscript.com/autoit3/docs/keywords.htm#Return) SetError (http://www.autoitscript.com/autoit3/docs/functions/SetError.htm)(@error (http://www.autoitscript.com/autoit3/docs/macros.htm#@error), 0, $aRet)
EndFunc (http://www.autoitscript.com/autoit3/docs/keywords.htm#EndFunc)
?
:)
madmasles
22-01-2010, 00:19
Creat0R,
Вот время работы Вашей функции у меня 376.28 - Супер!!!
Результат функции от asdf8 1763.56
PS
Рано еще списывать командную строку.
А так: »
первый прогон 4037.44
второй прогон 3680.5
для моей функции:
первый прогон 4667.5
второй прогон 1587.21
Интересно - можно еще быстрее?
для моей функции »
У себя не замечаю такую разницу, функция с использованием Dir отрабатывает намного быстрее чем всё остальное.
Интересно - можно еще быстрее? »
Сарказм? к чему оно?
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC