Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [решено] Рекурсивный поиск файла

Ответить
Настройки темы
[решено] Рекурсивный поиск файла

Новый участник


Сообщения: 31
Благодарности: 1

Профиль | Отправить PM | Цитировать


Изменения
Автор: cra5h_
Дата: 20-01-2010
Поиск файла выполняется при помощи функции, и выполняется очень долго. Возможно ли реализовать поиск файла в каталогах и подкаталогах другим способом - более быстрым?

Код: Выделить весь код
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?
Это сообщение посчитали полезным следующие участники:

Отправлено: 10:37, 20-01-2010

 

Аватара для Sp01LeR

Пользователь


Сообщения: 60
Благодарности: 13

Профиль | Отправить PM | Цитировать


Цитата:
Можно ли организовать поиск файла через WinAPI
Цитата:
Врядли оно будет быстрее (в AutoIt).
В WinAPI есть продвинутая функция FindFirstFileEx(работает только в win2000 и выше) - вот ссылка на мануал

Отправлено: 16:13, 21-01-2010 | #11



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 27
Благодарности: 11

Профиль | Отправить PM | Цитировать


Можно значительно ускорить поиск файлов, если избавиться от рекурсии.
Много времени уходит на многочисленный вызов функции.

Отправлено: 17:29, 21-01-2010 | #12


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата asdf8:
Можно значительно ускорить поиск файлов, если избавиться от рекурсии. »
Вот так:

Код: Выделить весь код
$sFile = _FileSearch(@DesktopDir, "test.txt")
MsgBox(64, 'Title', $sFile)

Func _FileSearch($sPath, $sMask="*")
    If Not StringInStr(FileGetAttrib($sPath & "\"), "D") Then Return SetError(1, 0, 0)

    Local $hSearch, $sFindNext, $sFilePath, $iPathIsFolder, $i = 0, $sRet = -1
    Local $sRegExpFilter = StringReplace(StringReplace(StringReplace($sMask, ".", "\."), "*", ".*"), "?", ".")
    Local $iMax_Ret_Paths = 10000
    Local $aPathesArr[$iMax_Ret_Paths+1] = [1, $sPath]

    While $i < $aPathesArr[0]
        $i += 1

        $hSearch = FileFindFirstFile($aPathesArr[$i] & "\*")
        If $hSearch = -1 Then ContinueLoop

        While 1
            $sFindNext = FileFindNextFile($hSearch)
            If @error Then ExitLoop

            $sFilePath = $aPathesArr[$i] & "\" & $sFindNext
            $iPathIsFolder = StringInStr(FileGetAttrib($sFilePath & "\"), "D")

            If $iPathIsFolder Then
                If $aPathesArr[0] >= $iMax_Ret_Paths Then
                    $iMax_Ret_Paths *= 2
                    ReDim $aPathesArr[$iMax_Ret_Paths+1]
                EndIf

                $aPathesArr[0] += 1
                $aPathesArr[$aPathesArr[0]] = $sFilePath
            ElseIf StringRegExp($sFindNext, "(?i)\A" & $sRegExpFilter & "\z") Then
                $sRet = $sFilePath
                ExitLoop
            EndIf
        WEnd

        FileClose($hSearch)
        If $sRet <> -1 Then ExitLoop
    WEnd

    Return SetError(Number($sRet = -1), 0, $sRet)
EndFunc

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 18:06, 21-01-2010 | #13


Новый участник


Сообщения: 27
Благодарности: 11

Профиль | Отправить PM | Цитировать


Цитата Creat0R:
Вот так: »

Код: Выделить весь код
#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 раз быстрее, чем из предыдущего поста
Это сообщение посчитали полезным следующие участники:

Отправлено: 18:36, 21-01-2010 | #14


Аватара для semiono

Ветеран


Сообщения: 830
Благодарности: 33

Профиль | Отправить PM | Цитировать


Будте любезны зделайте мне этот пример по типам *.reg и с запуском $regfiles /s
И не ругайтесь, что я встреваю, но не понял что ищете все файлы ($includeFilter='*.txt,*.htm') чтоли? Зделайте по типам!
(GUI вывод мне не нужен...)

-------
Полезное сообщение


Отправлено: 20:17, 21-01-2010 | #15


Новый участник


Сообщения: 27
Благодарности: 11

Профиль | Отправить PM | Цитировать


Цитата semiono:
пример по типам *.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 указать, где искать файлы.
Это сообщение посчитали полезным следующие участники:

Отправлено: 20:55, 21-01-2010 | #16


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата asdf8:
Этот скрипт осматривает папку WindowsDir в 6 раз быстрее, чем из предыдущего поста »
А так:

Код: Выделить весь код
#include <Array.au3>

$begin1 = TimerInit()
$aReturn = _FileSearch(@WindowsDir, "*.ini")
$dif1 = TimerDiff($begin1)

_ArrayDisplay($aReturn, Round($dif1, 2))

Func _FileSearch($sPath, $sFileMask)
    Local $iPID, $sStdOutRead, $aRet

    $iPID = Run(@ComSpec & ' /C Dir "' & $sPath & '\' & $sFileMask & '" /S /B /A RASH', @SystemDir, @SW_HIDE, 6)

    While 1
        $sStdOutRead &= StdoutRead($iPID)
        If @error <> 0 Then ExitLoop
    WEnd

    $aRet = StringSplit(StringStripCR(StringStripWS($sStdOutRead, 3)), @LF)
    Return SetError(@error, 0, $aRet)
EndFunc
?

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community

Это сообщение посчитали полезным следующие участники:

Отправлено: 00:06, 22-01-2010 | #17


Аватара для madmasles

Ветеран


Сообщения: 812
Благодарности: 353

Профиль | Отправить PM | Цитировать


Creat0R,

Вот время работы Вашей функции у меня 376.28 - Супер!!!
Результат функции от asdf8 1763.56

PS

Рано еще списывать командную строку.

Отправлено: 00:19, 22-01-2010 | #18


Новый участник


Сообщения: 27
Благодарности: 11

Профиль | Отправить PM | Цитировать


Цитата Creat0R:
А так: »
первый прогон 4037.44
второй прогон 3680.5

для моей функции:
первый прогон 4667.5
второй прогон 1587.21

Интересно - можно еще быстрее?

Отправлено: 01:34, 22-01-2010 | #19


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата asdf8:
для моей функции »
У себя не замечаю такую разницу, функция с использованием Dir отрабатывает намного быстрее чем всё остальное.

Цитата asdf8:
Интересно - можно еще быстрее? »
Сарказм? к чему оно?

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 01:55, 22-01-2010 | #20



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [решено] Рекурсивный поиск файла

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
[решено] Поиск файла на компьютере sashadeg AutoIt 12 30-01-2010 18:40
Разное - [решено] Поиск по типу файла 7human7 Microsoft Windows 7 2 25-11-2009 09:51
Интерфейс - [решено] Быстрый поиск TEMA5 Microsoft Windows 7 7 07-10-2009 20:42
CMD/BAT - [решено] Как скопировать имя файла из текстового файла в код батника и т.д. Nun-Nun Скриптовые языки администрирования Windows 6 13-05-2009 13:28
Разное - [решено] поиск файлов zai Microsoft Windows 2000/XP 20 07-10-2007 14:18




 
Переход