Назад
7.30. Рекурсивный обход дерева каталогов
В примере показан способ рекурсивного обхода
дерева каталогов. Он может быть использован в
программах, выполняющих какие-либо действия над
файлами, расположенными в деревьях каталогов,
например, для перекодировки или подсчета
контрольной суммы группы файлов.
Исходный текст примера
Архив проекта для Java WorkShop 2.0
Немного теории
Одна из часто встречающихся в программировании
задач - это обход дерева каталогов с целью
выполнения над всеми расположенными там файлами
какой-либо операции. В качестве примера можно
привести перекодировку документов HTML с
символами кириллицы из кодировки KOI-8 в кодировки
DOS или Windows.
Для обхода каталогов проще всего
воспользоваться механизмом рекурсивного вызова
методов, предусмотренном в языке
программирования Java. В этом случае некоторый
рекурсивный метод мог бы получать список
содержимого каталога, путь к которому передан
ему через параметр. Далее для всех каталогов,
расположенных в данном каталоге, этот метод мог
бы вызывать сам себя, передавая себе полный путь
к обнаруженному подкаталогу.
Что же касается списка содержимого каталога, то
его нетрудно получить с помощью метода list,
определенного в классе File.
Описание примера
После запуска наша программа запрашивает на
консоли путь к каталогу. Далее она обходит дерево
каталогов, расположенное в указанном каталоге.
При этом на консоль выводятся полные пути к
обнаруженным файлам:
Enter full path ('quit' to exit):
c:\ut\other
c:\ut\other\DD\DD.EXE
c:\ut\other\DD\MSDUSER.DAT
c:\ut\other\DD\SERIAL.SER
c:\ut\other\NCDC\!COLLAPS.ARJ
c:\ut\other\NCDC\DCENU.GID
c:\ut\other\OS2\NET.CFG
c:\ut\other\PKZFIND.EXE
c:\ut\other\PKZFIN~1.PIF
c:\ut\other\VTREK.EXE
c:\ut\other\VTREKE~1.PIF
c:\ut\other\ZIP2EXE.EXE
Enter full path ('quit' to exit):
Рассмотрим исходный текст приложения.
Вся полезная работа делается внутри методов main
и list, определенных в главном классе приложения
DirTree:
import java.io.*;
import java.util.*;
public class DirTree
{
public static void main(String args[])
{
. . .
}
static void list(String szDir)
{
. . .
}
}
Метод main
Метод main создает цикл, внутри которого он
запрашивает у пользователя путь к исходному
каталогу и отображает расположенные в дереве
каталогов файлы.
Ввод пути к исходному каталогу выполняется
методом getKbdString, определенном в нашем приложении:
String s;
while(true)
{
System.out.println(
"Enter full path ('quit' to exit): ");
s = new String(getKbdString());
if(s.equals("quit"))
break;
. . .
}
Цикл завершается, когда пользователь вводит
строку "quit".
Далее метод main проверяет, существует ли
введенный путь и указывает ли он на каталог:
File f = new File(s);
if(!f.exists())
{
System.out.println("\nNot found: " + s);
continue;
}
if(!f.isDirectory())
{
System.out.println(
"\nNot directory: " + s);
continue;
}
При ошибке пользователю предлагается
повторить ввод пути к каталогу.
Если же путь введен правильно, метод main
вызывает метод list, определенный в нашем
приложении:
list(s);
Этот метод распечатывает на консоли содержимое
дерева каталогов.
Метод list
В качестве единственного параметра метод list
получает путь к каталогу szDir:
static void list(String szDir)
{
. . .
}
Для каталога szDir метод list создает объект класса
File:
File f = new File(szDir);
Далее метод заполняет массив sDirList списком имен
содержимого каталога, путь к которому задан
параметром szDir:
String[] sDirList = f.list();
Обработка содержимого каталога выполняется в
цикле:
int i;
for(i = 0; i < sDirList.length; i++)
{
File f1 = new File(szDir +
File.separator + sDirList[i]);
if(f1.isFile())
System.out.println(szDir +
File.separator + sDirList[i]);
else
{
list(szDir +
File.separator + sDirList[i]);
}
}
Здесь мы создаем для каждого обнаруженного в
каталоге файла или каталога объект класса File.
Если мы обнаружили файл, мы выводим на консоль
полный путь к нему, комбинируя его из пути к
каталогу szDir и имени каталога.
При обнаружении каталога метод list вызывает сам
себя, передавая себе через параметр полный путь к
обнаруженному каталогу. Это и есть рекурсивный
вызов метода list.
Назад |