Каталог с подкаталогами

rinsk

Lotus team
12.11.2009
900
44
#1
это типа получать список файлов в каталоге?
а не проще в шел команду сунуть? ;)
в вянде dir /s b /o
в никсах - подходящий вариант ls или find (зависит от цели получения списка)
lmike - фи, как неспортивно!;) Я то уж думал че-ть на LS2J родится:)))

от первоначального топика (Каталог с подкаталогами) - однозначно напрашивался рекурсивный вызов для раскрытия вложенных групп... Однако иногда можно обойтись и стеком - в первом примере кода эт указатель по динамическому массиву, во втором - баловство со строками:)
 

lmike

нет, пердело совершенство
Премиум
27.08.2008
6 567
263
#2
Я то уж думал че-ть на LS2J родится
да запросто :)
тока 10-ть лет назад не было его ;)

и ещё...
мне совершенно не понятно - почему не используется рекурсия, для интерпретируемых языков - это обычная практика (ибо стек, формально, не ограничен)
 

lmike

нет, пердело совершенство
Премиум
27.08.2008
6 567
263
#3
вот например изящный код (не мой - http://www.exampledepot.com/egs/java.io/TraverseTree.html) прикручивается к LS2J нараз (в process делаем вывод в ArrayList, по окончании преобразуем в String[])
переделал на "динамику" и добавил метод для LS2J:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Код</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='java'>import java.io.File;
import java.util.ArrayList;

public class DirProcess {
private static ArrayList arrFiles=new ArrayList();

public String[] Result() {
String[] result = new String[arrFiles.size()];
arrFiles.toArray(result);
return result;
}

public void visitAllDirsAndFiles(String dir){
arrFiles.clear();
visitAllDirsAndFiles(new File(dir));
}

public void visitAllDirs(String dir) {
arrFiles.clear();
visitAllDirs(new File(dir));
}

private void process(File dir) {
// TODO Auto-generated method stub
System.out.println(dir);
arrFiles.add(dir.toString());
}

public void visitAllDirsAndFiles(File dir) {
process(dir);
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
visitAllDirsAndFiles(new File(dir, children));
}
}
}

// Process only directories under dir
public void visitAllDirs(File dir) {
if (dir.isDirectory()) {
process(dir);
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
visitAllDirs(new File(dir, children));
}
}
}

// Process only files under dir
public void visitAllFiles(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
visitAllFiles(new File(dir, children));
}
} else {
process(dir);
}
}

public static void main(String args[]) {
DirProcess dirproc=new DirProcess();
dirproc.visitAllFiles(new File("myStartFolder"));
}
}[/CODE]
 

VladSh

начинающий
Lotus team
11.12.2009
1 260
5
#4
и ещё...
мне совершенно не понятно - почему не используется рекурсия, для интерпретируемых языков - это обычная практика (ибо стек, формально, не ограничен)
Особенность реализации LS-функции Dir - при попытке использовать её рекурсивно (Dir$ внутри Dir) вылетает ошибка "Illegal function call".
 

lmike

нет, пердело совершенство
Премиум
27.08.2008
6 567
263
#5
подправил класс
и сделал рапер (DirProcess - имя джава либы):
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Код LS2J</div></div><div class="sp-body"><div class="sp-content">
Код:
'********************************
'library DirProcess.LS2J
'********************************
Option Public
Option Declare
Use "ErrorHandling"
Uselsx "*lsxlc"
Use "DirProcess"

Const ERRBASE_DIRPROCESS=1130
Private Const ERRLS2JINIT=ERRBASE_DIRPROCESS+1, CS_ERRLS2JINIT={ошибка инициализации класса Java}

'********************************
Class DirObj As ErrorHandlerWJ
Private DirProcObj As JavaObject
Private DirProcClass As JavaClass
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub New()
On Error Goto errorhandler
Set DirProcClass = jSession.GetClass("DirProcess")
Set DirProcObj = DirProcClass.CreateObject
ExitFunction:
Exit Sub
errorhandler:
Call Me.RaiseError()
Error ERRLS2JINIT, CS_ERRLS2JINIT
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function Result() As Variant
Result=DirProcObj.Result()
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Sub VisitAllDirsAndFiles(startDir As String)
On Error Goto errorhandler
Call DirProcObj.visitAllDirsAndFiles(startDir)
ExitFunction:
Exit Sub
errorhandler:
Call Me.RaiseError()
Resume ExitFunction
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Sub VisitAllDirs(startDir As String)
On Error Goto errorhandler
Call DirProcObj.visitAllDirs(startDir)
ExitFunction:
Exit Sub
errorhandler:
Call Me.RaiseError()
Resume ExitFunction
End Sub
End Class
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">код для проверки (агент, таргет - none)</div></div><div class="sp-body"><div class="sp-content">
Код:
Option Public
Option Declare
Use "DirProcess.LS2J"
Sub Initialize
Dim dirProc As New DirObj
Call dirProc.visitAllDirs(".\data")
Dim result
result=dirProc.Result
Forall m In result
Print Cstr(m)
End Forall
End Sub
 

VladSh

начинающий
Lotus team
11.12.2009
1 260
5
#6
public String[] Result() я бы сделал как private и дёргал бы из visitAllDirsAndFiles и visitAllDirs, и результат return'ом сразу же выдавал на гора.. а то что-то код разбух сильно.
И имеет ли смысл класс на LS, который просто транслирует вызовы?

Чуть попроще (вызовы потом будут покомпактнее):
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Код</div></div><div class="sp-body"><div class="sp-content">
Код:
%REM
Library FS
Description: функционал для работы с файловой системой
%END REM
Uselsx "*javacon"

Private jSession As JavaSession
Private jDirProcCls As JavaClass


Private Function initDirProcess() As JavaObject
On Error Goto ErrH
Static jDirProcObj As JavaObject

If jDirProcObj Is Nothing Then
Set jSession = New JavaSession()
Set jDirProcCls = jSession.GetClass("DirProcess")
Set jDirProcObj = jDirProcCls.CreateObject
End If

Set initDirProcess = jDirProcObj
Exit Function

ErrH:
'свой обработчик (по желанию)
Exit Function
End Function


Public Function GetSubFiles(startDir As String)
On Error Goto ErrH
GetSubFiles = initDirProcess().visitAllDirs(startDir)
Exit Function

ErrH:
'свой обработчик
Exit Function
End Function
 

lmike

нет, пердело совершенство
Премиум
27.08.2008
6 567
263
#7
абисню :)
-ф-ции обхода ФС "сбрасывают" массив, а использовать результат я могу захотеть неоднократно
-инициализация джава объектов, при каждом вызове - мне не очень нра
-класс хранит инстанс джава объекта и стало-быть - собственная жизнь (в рамках приложения), что бывает удобно (при одновременном использовании нескольких)
 

lmike

нет, пердело совершенство
Премиум
27.08.2008
6 567
263
#8
если посмотреть - я одну ф-цию не обернул (только файлы - visitAllFiles) - это для самостоятельной работы, кто заинтересуется :)
и LS класс можно дописать/переписать - сразу делать возврат резалта (ежели кому-то именно так надо)
 

VladSh

начинающий
Lotus team
11.12.2009
1 260
5
#9
-ф-ции обхода ФС "сбрасывают" массив, а использовать результат я могу захотеть неоднократно
сразу в переменную результат взять и пользовать эту переменную сколько угодно?

-инициализация джава объектов, при каждом вызове - мне не очень нра
-класс хранит инстанс джава объекта и стало-быть - собственная жизнь (в рамках приложения), что бывает удобно (при одновременном использовании нескольких)
у меня в коде также происходит: Private в Declarations (можно не людить гл.пер, но в этом случае, по моему, это оправдано) и Static.
 

lmike

нет, пердело совершенство
Премиум
27.08.2008
6 567
263
#10
сразу в переменную результат взять и пользовать эту переменную сколько угодно?
так и есть - в ArrayList ...

если пишем для джава - то былоб неоправдано не использовать и в др. сучностях java
а "фиксировать" (в переменной) "неудобный" (String[]) объект, в джава - нет смысла (он для LS)...
у ArrayList легко делается сортировка (а на выходе получим тотже String[]), и прочие прелести работы с List-ами
со стороны LS - мы не можем передавать динамические массивы (в джава), с Variant - тоже много особенностей
фиксация массива во врапере (в доп. переменной) будет лишней (нужно обнулять)

др. словами - тек. реализация, ИМХО, удобна для модификации и параллельного использования (java и LS2J)
а дальнейшая заточка (под свои взгляды/нужды) - дело пользующего :)
 

VladSh

начинающий
Lotus team
11.12.2009
1 260
5
#11
lmike
понЯл :(

Тогда Java-класс я бы разбил на 2: базовый (для использования в Java) и наследуемый от него (для LS2J).
ну или так бы уже делал:
Код:
Public Function VisitAllDirsAndFiles(startDir As String) As Variant
...
Call DirProcObj.visitAllDirsAndFiles(startDir)
Me.VisitAllDirsAndFiles = DirProcObj.Result()
...
End Function
...