PDA

Показать полную графическую версию : [решено] Рекурсивный поиск файла


Страниц : 1 [2] 3

amel27
22-01-2010, 12:47
Интересно - можно еще быстрее? »
второй прогон можно, если результат первого сохранить в файл... :teeth:

asdf8
22-01-2010, 13:58
Сарказм? »
Конечно нет.
Есть программка FindOnClick, которая ищет файлы на порядок быстрее всего того, что я вообще видел.
Думал, может кто знает, как?

madmasles
22-01-2010, 14:40
Присоединяюсь к вопросу asdf8.
FindOnClick действительно очень быстро ищет файлы.

Creat0R
22-01-2010, 17:56
Вам нужна скорость, покурите функций _FileListToArray* из темы на оф. форуме: Improvement of included _FileListToArray function (http://www.autoitscript.com/forum/index.php?showtopic=96952&st=0)
Там было предложено немало хороших улучшений.

Creat0R
22-01-2010, 18:34
Есть программка FindOnClick, которая ищет файлы на порядок быстрее всего того, что я вообще видел. »
Ну вообще то она поддерживает командную строку, думает будет не сложно использовать её в качестве "поисковика"?

timsky
22-01-2010, 19:03
Windows 7 x64 Ultimate. Поиск @WindowsDir, "*.*":

Вариант asdf8 из этого поста (http://forum.oszone.net/post-1326260-14.html) 17590 мсек и находит 66247 файлов.

Вариант Creat0R из этого поста (http://forum.oszone.net/post-1326507-17.html) 3828 мсек и находит 81241 файлов.


TotalCommander 7.50a (включено отображение скрытых файлов) находит 64237 файлов и 14557 папок за 34 секунды.
ViewFD 2.4.3.0 (дефолтовые опции) находит 64240 файлов за 2 секунды.

Проводник 76757 объектов
При включенном отображении скрытых файлов - 76908
При включенном отображении скрытых и системных файлов - 77054

SearchMyFiles 1.37 от NirSoft.net - 64243 файла и 14525 папок.


ЗЫ: тестил в таком же порядке, в котором отписал.

Creat0R
22-01-2010, 20:23
Вариант asdf8 из этого поста 17590 мсек и находит 66247 файлов.
Вариант Creat0R из этого поста 3828 мсек и находит 81241 файлов. »
Мой вариант ищет все файлы, включая скрытые, только для чтения, архивные и системные.

тестил в таком же порядке, в котором отписал »
Но эти тесты почти ничего не показывают, т.к поиск возвращает разное количество файлов.

timsky
23-01-2010, 03:07
Но эти тесты почти ничего не показывают, т.к поиск возвращает разное количество файлов. »
Я и ничего не пытался доказать.

Просто заметил, что файловые менеджеры и SearchMyFiles возвращают примерно одинаковое кол-во файлов (м/у запусками немного различается), твой вариант выдает больше всего файлов, а вот вариант asdf8 как-то не вписывается в общую картину.
У проводника Виндовс вообще свои соображения на сей счет, только ему известные. :)

Sp01LeR
24-01-2010, 22:04
По моим наблюдениям, самый быстрый поиск файлов, это поиск напрямую через файловую систему раздела - такая функция есть у большинства продвинутых утилит для востановления удаленных(поврежденных) файлов, правда по скорости чтения они тоже показывают разные результаты...

madmasles
04-02-2010, 19:12
Creat0R,
$iPID = Run(@ComSpec & ' /C ChCp 1251 & Dir "' & $sPath & '\' & $sFileMask & '" /S /B /A RASH', @SystemDir, @SW_HIDE, 6) »
У меня не работает.
На скриншоте ˜Ё«®ў - это юзер русскими буквами, ђ*Ў®зЁ© бв®« - Рабочий стол.
Почему, не понятно?

Iska
04-02-2010, 19:51
К сожалению, такой способ не сработает, поскольку несмотря на то, что chcp выполнится, и кодовая страница сменится… Дело в том, что узнает об этом изменении только команда в следующей строке, а не в текущей: VBScript: запуск консольного приложения с чтением его вывода (http://forum.script-coding.info/viewtopic.php?id=923), см. примечание в конце. Сие можно также проверить, перенаправив вывод в текстовый файл в том и другом примере.

Creat0R
04-02-2010, 19:55
узнает об этом изменении только команда в следующей строке, а не в текущей »
Оказывается что в таком образе даже следующая строка не принимает кодовую страницу, я пробовал создавать временный бат-файл с двумя строками, что при выводе в поток, что при выводе в файл, код. страница не меняется :(

madmasles
04-02-2010, 20:09
Iska,
Creat0R,
Значит я был прав насчет Encoding_UDF. А то я расстроился, думал опять руки кривые.

Iska
04-02-2010, 21:15
Оказывается что в таком образе даже следующая строка не принимает кодовую страницу, я пробовал создавать временный бат-файл с двумя строками, что при выводе в поток, что при выводе в файл, код. страница не меняется
Хмм… Речь только про пакетные файлы? Или в трактовке чтения вывода в 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, если не сложно, приведите Ваш код, как Вы пробовали.

Creat0R
04-02-2010, 23:55
приведите Ваш код, как Вы пробовали »
Примерно так:


$sBat = _
'@echo off' & @CRLF (http://www.autoitscript.com/autoit3/docs/macros.htm#@CRLF) & _
'chcp 1251 > nul' & @CRLF (http://www.autoitscript.com/autoit3/docs/macros.htm#@CRLF) & _
'dir /b "' & @DesktopDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@DesktopDir) & '\*.txt"'

$hFile = FileOpen (http://www.autoitscript.com/autoit3/docs/functions/FileOpen.htm)("test_dir.bat", 2)
FileWrite (http://www.autoitscript.com/autoit3/docs/functions/FileWrite.htm)($hFile, $sBat)
FileClose (http://www.autoitscript.com/autoit3/docs/functions/FileClose.htm)($hFile)

$sSdOutRead = ""
$iPid = Run (http://www.autoitscript.com/autoit3/docs/functions/Run.htm)(@DesktopDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@DesktopDir) & '\test_dir.bat', @DesktopDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@DesktopDir), @SW_HIDE (http://www.autoitscript.com/autoit3/docs/macros.htm#@SW_HIDE), 2)

While (http://www.autoitscript.com/autoit3/docs/keywords.htm#While) 1
$sSdOutRead &= 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)

ConsoleWrite (http://www.autoitscript.com/autoit3/docs/functions/ConsoleWrite.htm)($sSdOutRead & @CRLF (http://www.autoitscript.com/autoit3/docs/macros.htm#@CRLF))

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

#include <Array.au3>

$aReturn = _FileSearch(@DesktopDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@DesktopDir), "*.txt")
_ArrayDisplay($aReturn)

Func (http://www.autoitscript.com/autoit3/docs/keywords.htm#Func) _FileSearch($sPath, $sFileMask)
Local (http://www.autoitscript.com/autoit3/docs/keywords.htm#Local) $sBatContent, $sBatFile, $sTmpFile, $hFile, $sRet, $aRet

$sBatFile = @TempDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@TempDir) & "\~FileSearch.bat"
$sTmpFile = @TempDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@TempDir) & "\~FileSearch.tmp"

$sBatContent = _
'@ECHO OFF' & @CRLF (http://www.autoitscript.com/autoit3/docs/macros.htm#@CRLF) & _
'CHCP 1251 > Nul' & @CRLF (http://www.autoitscript.com/autoit3/docs/macros.htm#@CRLF) & _
'Dir "' & $sPath & '\' & $sFileMask & '" /S /B /A RASH>"%Temp%\~FileSearch.tmp'

$hFile = FileOpen (http://www.autoitscript.com/autoit3/docs/functions/FileOpen.htm)($sBatFile, 2)
FileWrite (http://www.autoitscript.com/autoit3/docs/functions/FileWrite.htm)($hFile, $sBatContent)
FileClose (http://www.autoitscript.com/autoit3/docs/functions/FileClose.htm)($hFile)

RunWait (http://www.autoitscript.com/autoit3/docs/functions/RunWait.htm)($sBatFile, @TempDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@TempDir), @SW_HIDE (http://www.autoitscript.com/autoit3/docs/macros.htm#@SW_HIDE))
$sRet = FileRead (http://www.autoitscript.com/autoit3/docs/functions/FileRead.htm)($sTmpFile)

FileDelete (http://www.autoitscript.com/autoit3/docs/functions/FileDelete.htm)($sBatFile)
FileDelete (http://www.autoitscript.com/autoit3/docs/functions/FileDelete.htm)($sTmpFile)

$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)($sRet, 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)

80971815772
05-02-2010, 03:14
есть - ф-ция у Креатора,мне она очень понравилась.Но в чем проблема...


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:09
80971815772, в оригинале эта функция таки возвращала полный список:

#include <Array.au3>

$aFiles = _FileSearch(@DesktopDir (http://www.autoitscript.com/autoit3/docs/macros.htm#@DesktopDir), "*.txt")

_ArrayDisplay($aFiles)

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 = ""
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 & @CRLF (http://www.autoitscript.com/autoit3/docs/macros.htm#@CRLF)
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)
WEnd (http://www.autoitscript.com/autoit3/docs/keywords.htm#WEnd)

$sRet = StringSplit (http://www.autoitscript.com/autoit3/docs/functions/StringSplit.htm)(StringStripWS (http://www.autoitscript.com/autoit3/docs/functions/StringStripWS.htm)($sRet, 3), @CRLF (http://www.autoitscript.com/autoit3/docs/macros.htm#@CRLF), 1)
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) Return (http://www.autoitscript.com/autoit3/docs/keywords.htm#Return) SetError (http://www.autoitscript.com/autoit3/docs/functions/SetError.htm)(1, 0, -1)

Return (http://www.autoitscript.com/autoit3/docs/keywords.htm#Return) $sRet
EndFunc (http://www.autoitscript.com/autoit3/docs/keywords.htm#EndFunc)

amel27
05-02-2010, 12:14
забыл убрать флаг указывающий на вывод в поток »
может всё-таки через поток?..
#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

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

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

madmasles
05-02-2010, 12:36
amel27,
Creat0R,
Объясните, пожалуйста, про ключ /U . В справках ничего про него не нашел.




© OSzone.net 2001-2012