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

Компьютерный форум 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

 

Ветеран


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

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


К сожалению, такой способ не сработает, поскольку несмотря на то, что chcp выполнится, и кодовая страница сменится…
читать дальше »
Дело в том, что узнает об этом изменении только команда в следующей строке, а не в текущей: vbscript: запуск консольного приложения с чтением его вывода, см. примечание в конце. Сие можно также проверить, перенаправив вывод в текстовый файл в том и другом примере.

Отправлено: 19:51, 04-02-2010 | #31



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

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


Аватара для Creat0R

Must AutoIt


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

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


Цитата Iska:
узнает об этом изменении только команда в следующей строке, а не в текущей »
Оказывается что в таком образе даже следующая строка не принимает кодовую страницу, я пробовал создавать временный бат-файл с двумя строками, что при выводе в поток, что при выводе в файл, код. страница не меняется

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

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

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


Отправлено: 19:55, 04-02-2010 | #32


Аватара для madmasles

Ветеран


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

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


Iska,
Creat0R,
Значит я был прав насчет Encoding_UDF. А то я расстроился, думал опять руки кривые.

Отправлено: 20:09, 04-02-2010 | #33


Ветеран


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

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


Цитата Creat0R:
Оказывается что в таком образе даже следующая строка не принимает кодовую страницу, я пробовал создавать временный бат-файл с двумя строками, что при выводе в поток, что при выводе в файл, код. страница не меняется
Хмм… Речь только про пакетные файлы? Или в трактовке чтения вывода в AutoIt? А то я что-то запутался. Для пакетных файлов у меня такое работает:

читать дальше »
0001.cmd
Код: Выделить весь код
chcp 1251>nul
pushd "%ProgramFiles%" && dir
0002.cmd
Код: Выделить весь код
chcp 1251>nul && pushd "%ProgramFiles%" && dir
И тот и другой пакетный файл запускаю в отдельном интерпретаторе команд «cmd.exe» (с умолчальной кодовой страницей 866), как:
Код: Выделить весь код
0001.cmd > 0001.txt
и
Код: Выделить весь код
0002.cmd > 0002.txt
соответственно. В результате получаю два текстовых файла (привожу частичные копии с экрана редактора Far Manager, кодировка указана в верхней строке):
Код: Выделить весь код
C:\03\0001.txt                                           Win-1251  Строка

C:\03>chcp 1251 1>nul

C:\03>pushd "C:\Program Files"   && dir
 Том в устройстве C не имеет метки.
 Серийный номер тома: 246E-586A

 Содержимое папки C:\Program Files

04.02.2010  16:33    <DIR>          .
04.02.2010  16:33    <DIR>          ..
19.01.2009  10:09    <DIR>          7-Zip
01.08.2008  20:00    <DIR>          Account Lockout and Management Tools
…
Код: Выделить весь код
C:\03\0002.txt                                                DOS  Строка

C:\03>chcp 1251  1>nul  && pushd "C:\Program Files"   && dir
 Том в устройстве C не имеет метки.
 Серийный номер тома: 246E-586A

 Содержимое папки C:\Program Files

04.02.2010  16:33    <DIR>          .
04.02.2010  16:33    <DIR>          ..
18.06.2009  11:37    <DIR>          01
19.01.2009  10:09    <DIR>          7-Zip
01.08.2008  20:00    <DIR>          Account Lockout and Management Tools
…
Первый («0001.txt») в кодировке OEM, второй («0002.txt») — в кодировке ANSI.

Creat0R, если не сложно, приведите Ваш код, как Вы пробовали.

Отправлено: 21:15, 04-02-2010 | #34


Аватара для Creat0R

Must AutoIt


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

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


Цитата Iska:
приведите Ваш код, как Вы пробовали »
Примерно так:

Код: Выделить весь код
$sBat = _
    '@echo off' & @CRLF & _
    'chcp 1251 > nul' & @CRLF & _
    'dir /b "' & @DesktopDir & '\*.txt"'

$hFile = FileOpen("test_dir.bat", 2)
FileWrite($hFile, $sBat)
FileClose($hFile)

$sSdOutRead = ""
$iPid = Run(@DesktopDir & '\test_dir.bat', @DesktopDir, @SW_HIDE, 2)

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

ConsoleWrite($sSdOutRead & @CRLF)
Но я ошибся немного, при тестах с выводом в файл я забыл убрать флаг указывающий на вывод в поток - Так работает:

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

$aReturn = _FileSearch(@DesktopDir, "*.txt")
_ArrayDisplay($aReturn)

Func _FileSearch($sPath, $sFileMask)
    Local $sBatContent, $sBatFile, $sTmpFile, $hFile, $sRet, $aRet

    $sBatFile = @TempDir & "\~FileSearch.bat"
    $sTmpFile = @TempDir & "\~FileSearch.tmp"

    $sBatContent = _
        '@ECHO OFF' & @CRLF & _
        'CHCP 1251 > Nul' & @CRLF & _
        'Dir "' & $sPath & '\' & $sFileMask & '" /S /B /A RASH>"%Temp%\~FileSearch.tmp'

    $hFile = FileOpen($sBatFile, 2)
    FileWrite($hFile, $sBatContent)
    FileClose($hFile)

    RunWait($sBatFile, @TempDir, @SW_HIDE)
    $sRet = FileRead($sTmpFile)

    FileDelete($sBatFile)
    FileDelete($sTmpFile)

    $aRet = StringSplit(StringStripCR(StringStripWS($sRet, 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

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

Отправлено: 23:55, 04-02-2010 | #35


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


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

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


есть - ф-ция у Креатора,мне она очень понравилась.Но в чем проблема...


Код: Выделить весь код
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
можно ли както сделать,чтобы ф-ция не останавливалась только на том файле,которая нашла и запоминала путь каждого файла?
для чего мне это : хочетса сделать архив,в котором будут все найдены файлы с полными путями.


потому что пока вот что получилось... :


Код: Выделить весь код
 	 FileCopy(_FileSearch("c:\","test.ini"),"c:\temp.ini")
	 $OF = ("c:\temp.ini")
	_ZipAdd ("c:\temp.zip",$OF)
	 FileDelete ($OF)

но это не очень удачливо просто .
может ктото , чтото посоветует..)


,kkkkkkkk

Последний раз редактировалось Creat0R, 05-02-2010 в 12:01. Причина: Добавлен тег кода


Отправлено: 03:14, 05-02-2010 | #36


Аватара для Creat0R

Must AutoIt


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

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


80971815772, в оригинале эта функция таки возвращала полный список:

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

$aFiles = _FileSearch(@DesktopDir, "*.txt")

_ArrayDisplay($aFiles)

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

    Local $hSearch, $sFindNext, $sFilePath, $iPathIsFolder, $i = 0, $sRet = ""
    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 & @CRLF
            EndIf
        WEnd

        FileClose($hSearch)
    WEnd

    $sRet = StringSplit(StringStripWS($sRet, 3), @CRLF, 1)
    If @error Then Return SetError(1, 0, -1)

    Return $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


Отправлено: 12:09, 05-02-2010 | #37


Googler


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

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


Цитата Creat0R:
забыл убрать флаг указывающий на вывод в поток »
может всё-таки через поток?..
Код: Выделить весь код
#include <Array.au3>

$aReturn = _FileSearch(@DesktopDir, "*.txt")
_ArrayDisplay($aReturn)

Func _FileSearch($sPath, $sFileMask)
    Local $sOut = StringToBinary("0"& @CRLF, 2), $aOut
    Local $hDir = Run(@ComSpec & ' /U/C DIR "'& $sPath &'\'& $sFileMask &'" /S/B/A-D', @SystemDir, @SW_HIDE, 6)

    While 1
        $sOut &= StdoutRead($hDir, False, True)
        If @error Then ExitLoop
    Wend

    $aOut = StringRegExp(BinaryToString($sOut,2), "[^\r\n]+", 3)
    If @error Then Return SetError(1)

    $aOut[0] = UBound($aOut)-1
    Return $aOut
EndFunc
Это сообщение посчитали полезным следующие участники:

Отправлено: 12:14, 05-02-2010 | #38


Аватара для Creat0R

Must AutoIt


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

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


Цитата amel27:
может всё-таки через поток? »
Супер! про ключ /U я и забыл совсем. А вот что делает «StringToBinary("0"& @CRLF, 2)» в начале?

Цитата Creat0R:
что делает «StringToBinary("0"& @CRLF, 2)» в начале? »
Кажется понял, это для добавления счётчика в нулевой элемент - хитро

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

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

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


Отправлено: 12:24, 05-02-2010 | #39


Аватара для madmasles

Ветеран


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

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


amel27,
Creat0R,
Объясните, пожалуйста, про ключ /U . В справках ничего про него не нашел.

Отправлено: 12:36, 05-02-2010 | #40



Компьютерный форум 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




 
Переход