Показать полную графическую версию : [решено] Рекурсивный поиск файла
Интересно - можно еще быстрее? »
второй прогон можно, если результат первого сохранить в файл... :teeth:
Сарказм? »
Конечно нет.
Есть программка FindOnClick, которая ищет файлы на порядок быстрее всего того, что я вообще видел.
Думал, может кто знает, как?
madmasles
22-01-2010, 14:40
Присоединяюсь к вопросу asdf8.
FindOnClick действительно очень быстро ищет файлы.
Вам нужна скорость, покурите функций _FileListToArray* из темы на оф. форуме: Improvement of included _FileListToArray function (http://www.autoitscript.com/forum/index.php?showtopic=96952&st=0)
Там было предложено немало хороших улучшений.
Есть программка FindOnClick, которая ищет файлы на порядок быстрее всего того, что я вообще видел. »
Ну вообще то она поддерживает командную строку, думает будет не сложно использовать её в качестве "поисковика"?
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 папок.
ЗЫ: тестил в таком же порядке, в котором отписал.
Вариант asdf8 из этого поста 17590 мсек и находит 66247 файлов.
Вариант Creat0R из этого поста 3828 мсек и находит 81241 файлов. »
Мой вариант ищет все файлы, включая скрытые, только для чтения, архивные и системные.
тестил в таком же порядке, в котором отписал »
Но эти тесты почти ничего не показывают, т.к поиск возвращает разное количество файлов.
Но эти тесты почти ничего не показывают, т.к поиск возвращает разное количество файлов. »
Я и ничего не пытался доказать.
Просто заметил, что файловые менеджеры и SearchMyFiles возвращают примерно одинаковое кол-во файлов (м/у запусками немного различается), твой вариант выдает больше всего файлов, а вот вариант asdf8 как-то не вписывается в общую картину.
У проводника Виндовс вообще свои соображения на сей счет, только ему известные. :)
По моим наблюдениям, самый быстрый поиск файлов, это поиск напрямую через файловую систему раздела - такая функция есть у большинства продвинутых утилит для востановления удаленных(поврежденных) файлов, правда по скорости чтения они тоже показывают разные результаты...
madmasles
04-02-2010, 19:12
Creat0R,
$iPID = Run(@ComSpec & ' /C ChCp 1251 & Dir "' & $sPath & '\' & $sFileMask & '" /S /B /A RASH', @SystemDir, @SW_HIDE, 6) »
У меня не работает.
На скриншоте ˜Ё«®ў - это юзер русскими буквами, ђ*Ў®зЁ© бв®« - Рабочий стол.
Почему, не понятно?
К сожалению, такой способ не сработает, поскольку несмотря на то, что chcp выполнится, и кодовая страница сменится… Дело в том, что узнает об этом изменении только команда в следующей строке, а не в текущей: VBScript: запуск консольного приложения с чтением его вывода (http://forum.script-coding.info/viewtopic.php?id=923), см. примечание в конце. Сие можно также проверить, перенаправив вывод в текстовый файл в том и другом примере.
узнает об этом изменении только команда в следующей строке, а не в текущей »
Оказывается что в таком образе даже следующая строка не принимает кодовую страницу, я пробовал создавать временный бат-файл с двумя строками, что при выводе в поток, что при выводе в файл, код. страница не меняется :(
madmasles
04-02-2010, 20:09
Iska,
Creat0R,
Значит я был прав насчет Encoding_UDF. А то я расстроился, думал опять руки кривые.
Оказывается что в таком образе даже следующая строка не принимает кодовую страницу, я пробовал создавать временный бат-файл с двумя строками, что при выводе в поток, что при выводе в файл, код. страница не меняется
Хмм… Речь только про пакетные файлы? Или в трактовке чтения вывода в 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, если не сложно, приведите Ваш код, как Вы пробовали.
приведите Ваш код, как Вы пробовали »
Примерно так:
$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
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)
забыл убрать флаг указывающий на вывод в поток »
может всё-таки через поток?..
#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
может всё-таки через поток? »
Супер! про ключ /U я и забыл совсем. А вот что делает «StringToBinary("0"& @CRLF, 2)» в начале?
что делает «StringToBinary("0"& @CRLF, 2)» в начале? »
Кажется понял, это для добавления счётчика в нулевой элемент - хитро :)
madmasles
05-02-2010, 12:36
amel27,
Creat0R,
Объясните, пожалуйста, про ключ /U . В справках ничего про него не нашел.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC