Что нового

[Массивы] Структура каталога в масив массивов(супермассив), поиск по супермассиву

RUVATA

лучше один раз увидеть, чем десять раз услышать...
Сообщения
132
Репутация
38
Столкнувшись с задачей и после того как готового решения не нашлось, или они были не совсем по теме, или вообще "костыли"... решил разрабатывать определенный функционал сам

Вот такие инструменты у меня получились... с их помощью я достиг своей цели... и еще не раз наверное использую эти наработки...
Суть
Далле в коде описаны Две функции:
I. Struct_Reader([$TagertDir],[$OldDir]) -
$TagertDir - путь к целевому каталогу, поумолчанию = @ScriptDir
$OldDir - служебный параметр, если изучите код поймете зачем :smile:

Эта функция принемает первым параметром адрес изучаемого каталога, и возвращает массив массивов (обзовем его "супермассив" :IL_AutoIt_1: ) который описывает его структуру ;
Супермассив двухмерный, и все его подмассивы тоже,
в первой размерности имена (файлов/каталогов), а во второй:
1) для каталогов - содержит массив аналогичным образом описывающий его структуру и т.д.
2) для файлов - метка "file" (в идеале я думал о том, чтобы туда писать какую ни будь полезную инфу, но пока так)
PS: За нулевым индексом каждого из массивов закреплена "метаинформация" а именно в первой размерности полный путь к описываемому каталогу, во второй размерности специальные маркеры "no_files" или "no_dirs" или пусто(Nothing) если в каталог есть и те и другие.

II. Struct_Finder($TagertArray, [$TagertDir])
$TagertArray - наш супермассив :smile: возвращенный функцией Struct_Reader ; обработку подсовывания всякого "Г" я не делал... так что :whistle:
$TagertDir - поддиректория содержимое которой необходимо получить, по умолчанию = @ScriptDir

Эта функция возвращает срез массива массивов для указанной поддиректории

PS: Возвращаемый массив - является массивом одного из нижних порядков, но так-же как и родительский - супермассив, с определенным уровнем вложенности (если не описывает последний уровень вложенности).

Код:
#Include <File.au3>
#Include <Array.au3>

;Демонстрация
$Demonstration = Struct_Reader() ; Если исследуемый каталог не каталог скрипта, можно указать путь. н\п Struct_Reader('C:\') 
Struct_Finder($Demonstration) ; Вторым параметром этой функции можно задать конкретный каталог
;


Func Struct_Reader($TagertDir = @ScriptDir, $OldDir = "") 
Dim $Marker
Dim $FirstStep = 1


If StringRight($TagertDir, 1) <> "\" Then $TagertDir = $TagertDir & "\"
	
If $OldDir <> "" Then $TagertDir = $OldDir & $TagertDir
	
$Dirs=_FileListToArray($TagertDir, "*", 2) ; Определяем вложенные каталоги
	If (not IsArray($Dirs)) Then ; Если вложенных каталогов нет, объявляем пустой массив $Dirs
		Dim $Dirs[1]
		$Marker = "D"
	EndIf

$Files=_FileListToArray($TagertDir, "*", 1) ; Определяем вложенные файлы
	If (not IsArray($Files)) Then ; Если вложенных файлов нет, объявляем пустой массив $Files
		Dim $Files[1]
		$Marker = "F"
	EndIf
				
If Ubound($Dirs) + Ubound($Files) > 0 Then ; Подводим итоги предшествующих проверок, - стуктурируем массив
	Dim $Structure[$Dirs[0] + $Files[0] + 1][2]
	$Structure[0][0] = $TagertDir ; Сохраняем путь к опрошенному каталогу.	
	; Msgbox(0,"", $Structure[0][0])
		If $Marker = "D" Then $Structure[0][1] = "no_dirs"  ; Если в дирректории необнаруженно либо файлов либо каталогов 
		If $Marker = "F" Then $Structure[0][1] = "no_files" ; Оставляем "маркер" мне нужно было для отладки, хотя наверное можно найти и практическое прменение :)
			
		If $Marker <> "D" Then ; Если подиректории есть то опишем их, и отметим как "dir" для избиратеольной рекурсии
			For $i = 1 to UBound($Dirs) - 1	
					$Structure[$i][0] = $Dirs[$i]
					$Structure[$i][1] = "dir"
			Next
		Else
			$i = 1	
		EndIf 
		
		If $Marker <> "F" Then ; Если есть вложенные файлы - добавляем их к концу масиива, отмечаем как "File"
							   ; Это мой личный "бзык" так папки будут вверху файлы внизу//
			For $z = $i to $i + $Files[0] - 1 
					$Structure[$z][0] = $Files[$z - $i + 1]
					$Structure[$z][1] = "file" 
			Next	
		Endif
EndIf

For $i = 1 to Ubound($Structure) - 1    ; Собственно рекурсия функции
	If $Structure[$i][1] = "dir" Then 
		$FirstStep = 0
		; MSGbox(0, "", "$TagertDir = " & $Structure[$i][0] & " $OldDir = " & $Structure[0][0])
		$Structure[$i][1] = Struct_Reader($Structure[$i][0], $Structure[0][0]) 
		; _ArrayDisplay($Structure[$i][1] ,"$Structure")
	EndIf
Next

Return $Structure

EndFunc

Func Struct_Finder ($TagertArray, $TagertDir = "")

If $TagertDir = "" Then $TagertDir = $TagertArray[0][0]

If StringRight($TagertDir, 1) = "\" Then $TagertDir = StringTrimRight($TagertDir, 1)
If StringRight($TagertArray[0][0], 1) = "\" Then $TagertArray[0][0] = StringTrimRight($TagertArray[0][0], 1)

; Msgbox(0, "", "$TagertArray = " & $TagertArray[0][0] & " | $TagertDir = " & $TagertDir)

; Msgbox(0, "", $TagertArray[0][0] = $TagertDir)

If $TagertArray[0][0] <> $TagertDir Then
		For $i = 1 to UBound($TagertArray)-1
		If IsArray($TagertArray[$i][1]) Then Struct_Finder($TagertArray[$i][1], $TagertDir)
		Next
Else
	$Result = $TagertArray
EndIf

_ArrayDisplay($Result, "Result")

EndFunc
 
Автор
R

RUVATA

лучше один раз увидеть, чем десять раз услышать...
Сообщения
132
Репутация
38
Исправлен баг, касающийся обзора корневых и произвольных каталогов...

Спасибо, обнаружившему участнику Yashied

PS: обзор корневого каталога "C:\" занимает определенное время (т.к. мы получаем полный слепок), для демонстрации советую выбрать какой ни будь произвольный конкретный каталог
 
Верх