Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   текстовый файл с именами всех файлов в папке (http://forum.oszone.net/showthread.php?t=226945)

socap 03-02-2012 10:11 1850659

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

То есть папок например может быть указано и три и семь.

madmasles 03-02-2012 11:20 1850706

Цитата:

Цитата socap
все файлы указанных папок »

Указанных где? Все файлы с учетом подпапок или только самих папок? В текстовый файл писать только имена файлов или полные пути?

socap 03-02-2012 11:48 1850725

madmasles, указанных в самом скрипте.

Если можно, то пример с учетом подпапок и без учета.
То есть я например указываю $Dir1 с учетом, $Dir2 без учета.

Круто было бы если полный путь!

madmasles 03-02-2012 12:57 1850818

socap,
Код:

$Dir = @ScriptDir & '\AutoIt'

$aFilesAll = _FileSearch($Dir, '*', 1);с учетом подпапок
If @error Then
    MsgBox(16, 'Error', '_FileSearch')
    Exit
EndIf
$sText = 'С учетом подпапок' & @CRLF & 'Папка: ' & $Dir & @CRLF & 'Всего файлов: ' & $aFilesAll[0] & _
        @CRLF & 'На ' & @MDAY & '.' & @MON & '.' & @YEAR & ' ' & @HOUR & ':' & @MIN & @CRLF
For $i = 1 To $aFilesAll[0]
    $sText &= $i & '. ' & $aFilesAll[$i] & @CRLF
Next
$hFile = FileOpen(@ScriptDir & '\FilesAll.txt', 2)
FileWrite($hFile, StringTrimRight($sText, 2))
FileClose($hFile)
$aFiles = _FileSearch($Dir, '*', 1, 0);без учета подпапок
If @error Then
    MsgBox(16, 'Error', '_FileSearch')
    Exit
EndIf
$sText = 'Без учета подпапок' & @CRLF & 'Папка: ' & $Dir & @CRLF & 'Всего файлов: ' & $aFiles[0] & _
        @CRLF & 'На ' & @MDAY & '.' & @MON & '.' & @YEAR & ' ' & @HOUR & ':' & @MIN & @CRLF
For $i = 1 To $aFiles[0]
    $sText &= $i & '. ' & $Dir & '\' & $aFiles[$i] & @CRLF
Next
$hFile = FileOpen(@ScriptDir & '\Files.txt', 2)
FileWrite($hFile, StringTrimRight($sText, 2))
FileClose($hFile)


Func _FileSearch($sPath, $sFileMask = "*", $iFlag = 0, $iSubDir = 1, $iSort = 0)
    ;CreatoR; http://autoit-script.ru/index.php/topic,8266.msg55775
    Local $sOutBin, $sOut, $aOut, $aMasks, $sRead, $hDir, $sAttrib, $sFiles

    If Not StringInStr(FileGetAttrib($sPath), "D") Then
        Return SetError(1, 0, 0)
    EndIf
    If $iSubDir = 1 Then
        $sAttrib &= ' /S'
    EndIf
    If $iSort = 1 Then
        $sAttrib &= ' /O:N'
    EndIf
    Switch $iFlag
        Case 1
            $sAttrib &= ' /A-D'
        Case 2
            $sAttrib &= ' /AD'
        Case Else
            $sAttrib &= ' /A'
    EndSwitch
    $sOut = StringToBinary('0' & @CRLF, 2)
    $sPath = StringRegExpReplace($sPath, '\\+$', '')
    $sFileMask = StringRegExpReplace($sFileMask, '^;+|;+$', '')
    $sFileMask = StringRegExpReplace($sFileMask, ';{2,}', ';')
    $aMasks = StringSplit($sFileMask, ';')
    For $i = 1 To $aMasks[0]
        If StringStripWS($aMasks[$i], 8) = "" Then
            ContinueLoop
        EndIf
        $sFiles &= '"' & $sPath & '\' & $aMasks[$i] & '"'
        If $i < $aMasks[0] Then
            $sFiles &= ';'
        EndIf
    Next
    $hDir = Run(@ComSpec & ' /U /C DIR ' & $sFiles & ' /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)
    While 1
        $sRead = StdoutRead($hDir, False, True)
        If @error Then
            ExitLoop
        EndIf
        If $sRead <> "" Then
            $sOut &= $sRead
        EndIf
        Sleep(10)
    WEnd
    $aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
    If @error Or UBound($aOut) < 2 Then
        Return SetError(2, 0, 0)
    EndIf
    $aOut[0] = UBound($aOut) - 1
    Return $aOut
EndFunc  ;==>_FileSearch


apozlevich 03-02-2012 21:08 1851194

Цитата:

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

Фигассе вы заморочились. Есть же команда dir, которая с аргументом /B выводит только имена. Кстати, madmasles именно ее в итоге и использует в коде.

socap 04-02-2012 03:24 1851460

Спасибо! А как сделать так чтобы можно было ввести в скрипт например имя нескольких папок и все они были в этом текстовом файле?

Dm666 04-02-2012 04:07 1851468

Вот так еще можно
Код:

#include <File.au3>
#include <RecFileListToArray.au3>
Global $Dir[20]

$Dir[0] = "c:\Program Files\AutoIt3"
$Dir[1] = "c:\Windows"
$Dir[2] = "c:\Temp"

For $i = 0 To UBound($Dir) - 1
    If $Dir[$i] = "" Then ContinueLoop
    _Search($Dir[$i], 0)
    _Search($Dir[$i], 1)
Next

Func _Search($Dir, $iRecursion)
    $aFiles = _RecFileListToArray($Dir, "*.*", 1, $iRecursion, 0, 2, "", "")
    If Not IsArray($aFiles) Then
        MsgBox(16, "Error", "Invalid input path"& @CRLF & $Dir)
        Return
    Else
        If $iRecursion = 0 Then
            $hFile = FileOpen(@ScriptDir & "\NoRecursion.txt",1)
        Else
            $hFile = FileOpen(@ScriptDir & "\Recursion.txt",1)
        EndIf
        _FileWriteFromArray($hFile, $aFiles, 1)
        FileClose($hFile)
    EndIf
EndFunc

Udf брать здесь и положить в Autoit3\Include

AZJIO 16-02-2012 12:14 1860024

socap, до кучи
читать дальше »
Код:

#Include <FileOperations.au3>
$FileList=_FO_FileSearch(@WindowsDir, '*', True, 125, 1, 0)&@CRLF
$FileList &=_FO_FileSearch(@UserProfileDir, '*', True, 125, 1, 0)&@CRLF
$FileList &=_FO_FileSearch(@ProgramFilesDir&'\Internet Explorer', '*', True, 125, 1, 0)
$file = FileOpen(@ScriptDir&'\file.txt',2)
FileWrite($file, $FileList)
FileClose($file)



Только надо скачать это и положить файл FileOperations.au3 в папку "C:\Program Files\AutoIt3\Include"

apozlevich 16-02-2012 12:15 1860026

Так чем вам не нравится использование dir /B?

ferget 16-02-2012 12:34 1860043

apozlevich, это не труЪ

apozlevich 16-02-2012 12:36 1860045

Тогда надо использовать прямой доступ к секторам диска, вот это труъ труъ

AZJIO 16-02-2012 13:12 1860076

apozlevich
1. сравни скорость
2. Сравни вывод. dir /B при маске "*.doc" выведет файлы "*.docx", а оно надо, для этого я введу "*.doc?" или "*.doc*" если это понадобится.

apozlevich 16-02-2012 13:16 1860077

AZJIO, *.doc не выведет .docx, маска "*.doc" означает "все, что заканчивается на .doc" и .docx к этому не подходит. Кстати, у топикстартера нет задачи вывести по маске.
Скорость? Я даже моргнуть не успел, а dir уже отработал. Зато насколько меньше кода...

RUVATA 17-02-2012 12:47 1860750

вот
http://autoit-script.ru/index.php/topic,5259.0.html
я уже сталкивался с чем-то подобным... посмотри может пригодится...
Я периодически использую (немного видоизмененную под свои нужды)

socap 17-02-2012 14:31 1860841

AZJlO
Такой лаконичный код, спасибо.

Но не работает маска по расширениям почему-то.
Код:

#Include <FileOperations.au3>

$FileList =_FO_FileSearch('d:\Misc\', 'exe|jpg|png', True, 125, 1, 0)&@CRLF
;$FileList &=_FO_FileSearch('', '*', True, 125, 1, 0)&@CRLF

$FileList &=_FO_FileSearch('c:\windows', 'exe|jpg|png', True, 125, 1, 0)
$file = FileOpen(@ScriptDir&'\file.txt',2)
FileWrite($file, $FileList)
FileClose($file)

Выдает файл.тхт с двумя пустыми строчками.

AZJIO 17-02-2012 23:06 1861141

socap, должен работать, просто по умолчанию маска является полной, типа '*.exe|*.jpg|*.png', что позволяет использовать маску к примеру '*.in?|*.htm*|*.doc*'. Если необходимо использовать маску 'exe|jpg|png', то нужно указать параметр $iTypeMask=2 или $iTypeMask=0. Если что справка есть в самом UDF или здесь с подробным объяснением всех параметров, а они очень интересные (исключение/уровень вложенности/вид результата).
Там с UDF идёт в комплекте Gui, чтоб поиграть с параметрами. Вставляй путь, выбирай маску и смотри вывод.

socap 18-02-2012 20:08 1861562

AZJIO, а можно ли сделать маску исключения файлов по папкам?
То есть указываешь большую директорию (с кучей файлов и подпапок), исключаешь пару папок и файлы из исключенных папок в поиск не попадают?

И можно ли сделать маску по размеру файла?

kaster 18-02-2012 22:57 1861689

Цитата:

Цитата socap
И можно ли сделать маску по размеру файла? »

а это как? размер может быть либо больше определенного, либо меньше. а маска как будет работать?

AZJIO 19-02-2012 05:38 1861794

Цитата:

Цитата socap
AZJIO, а можно ли сделать маску исключения файлов по папкам? »

Можно, но не экономично получается, то есть заведомо тормозить выполнение сценария.
Например если добавить проверку в каждый запрос, то проверяется набор символов, при каждом запросе. Если сделать детект с помощью регулярного выражения, то скрипт будет обрабатывать этот каталог (холостой ход), потом вырезать ненужное. здесь специальную функцию лучше делать, дабы тем кому эта фича никогда не понадобилась не страдали.
Вообще такая UDF уже есть, смотри _RecFileListToArray в справке, по ссылке выше, но у неё недостаток в том, что она указывает папку, а не относительный путь к папке, то есть если указать в исключения 'папка1;папка2' то все эти папки будут игнорироваться, а обычно требуется исключить конкретную папку, а не одноимённые. И второй недостаток - используется с ключами $iReturn = 0 и $iRecur = 1, то есть возвращает папки и файлы.
Есть иной вариант _PathSearch, просто взять из неё регулярное выражение и с помощью него вырезать из результатов ненужные папки, примерно так

Код:

#include <Array.au3> ; для _ArrayDisplay
#include <FileOperations.au3>

$FileList=_FO_FileSearch(@WindowsDir, 'exe|dll', True, 125, 0, 0, 0)

$FileList = _ExcludePaths($FileList, 'system32\*|Microsoft.NET\*|assembly\*|WinSxS\*|RegisteredPackages\*')
MsgBox(0, 'Сообщение', $FileList)
$FileList = StringSplit($FileList, @CRLF, 1)
_ArrayDisplay($FileList, UBound($FileList) & ' - RegExp')

; Получение списка и обработка регулярным выражением
Func _ExcludePaths($FileList, $Mask)
    $Mask = StringReplace(StringReplace(StringRegExpReplace($Mask, '[][$^.{}()+\\]', '\\$0'), '?', '.'), '*', '.*?')
    $FileList = StringRegExpReplace($FileList & @CRLF, '(?mi)^(' & $Mask & ')\r\n', '')
    $FileList = StringReplace(StringTrimRight($FileList, 2), '|', '')
    Return $FileList
EndFunc

Если в _FO_FileSearch вывод относительных путей, то и в маске функции _ExcludePaths указывать относительные пути. Если в _FO_FileSearch указать возврат полных путей, то и в _ExcludePaths указывать лучше полные. В любом случае лучше элемент маски завершать символами "\*" что исключит детект файлов. Это не экономичный вариант, исключаемая папка будет сканироваться.

AZJIO 19-02-2012 16:42 1862088

Цитата:

Цитата socap
И можно ли сделать маску по размеру файла? »

Можно, есть даже функция от _FileFindEx от Ascend4nt. Насколько я понял она возвращает расширенную информацию о файле при каждом шаге поиске. Это работает быстрее нативных функций AutoIt3, которые сначала получают имя, а потом другими функциями можно получить атрибуты, размер и прочее.

Но в текущем варианте либо ручная правка UDF под свои запросы, либо результаты прогнать повторно в цикле, сравнивая с указанным размером. Для этого в начале получить данные в массив, потом проверить размеры и соответственно исключить
Код:

; Проверяем равенство и исключаем данные
For $i = 1 To $aFileList[0]
    If FileGetSize($aFileList[$i])=34579 Then $aFileList[$i]=''
Next

; Объединяем массив в список
$FileList=''
For $i = 1 To $aFileList[0]
    If $aFileList[$i] Then $FileList &= $aFileList[$i] &@CRLF
Next
$FileList=StringTrimRight($FileList, 2) ; обрезаем последние 2 символа



Время: 01:52.

Время: 01:52.
© OSzone.net 2001-