]]>
ваш баннер
]]>

Управление поиском файлов. Создание приложения на Java.

19 августа, 2007

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

Сделать это не сложно. Во-первых, в классе FileFinder мы добавляем переменную stop и метод stopSearch(), с помощь которых мы сможем прервать поиск. Во-вторых, создаём в библиотеке новый интерфейс SearchListener, а для его поддержки, в класс FileFinder мы добавляем список объектов (listeners), которые будут получать уведомления о ходе поиска, и метод addListener(), с помощью которого можно регистрировать новые объекты.

Посмотрим на исходный код класса FileFinder. Жирным шрифтом отмечены добавленные участки кода.

Code (java)
  1. /*
  2. * FileFinder.java
  3. *
  4. * Created on 13 Сентябрь 2006 г., 19:50
  5. */
  6.  
  7. package searchtools;
  8.  
  9. import java.io.File;
  10. import java.io.FilenameFilter;
  11. import java.util.ArrayList;
  12. import java.util.List;
  13. import java.util.regex.Matcher;
  14. import java.util.regex.Pattern;
  15.  
  16. /**
  17. * Этот класс предназначен для поиска файлов
  18. *
  19. * @author Стаценко Владимир
  20. * http://www.vova-prog.narod.ru
  21. */
  22. public class FileFinder {
  23.  
  24.     //классы для работы с регулярными выражениями
  25.     private Pattern p = null;
  26.     private Matcher m = null;
  27.  
  28.     //общий размер найденных файлов
  29.     private long totalLength = 0;
  30.     //общее количество найденных файлов
  31.     private long filesNumber = 0;
  32.     //общее количество просмотренных директорий
  33.     private long directoriesNumber = 0;
  34.  
  35.     //константы для определения объектов, которые нужно найти
  36.     private final int FILES = 0;
  37.     private final int DIRECTORIES = 1;
  38.     private final int ALL = 2;
  39.  
  40.     //список с объектами, которые должны быть уведомлены о состоянии поиска
  41.     private List listeners = null;
  42.     //используется для остановки поиска
  43.     private boolean stop = false;
  44.  
  45.     /** Создает новые экземпляры FileFinder */
  46.     public FileFinder() {
  47.     }
  48.  
  49.     /**
  50.      * Этот метод выполняет поиск всех объектов (файлов и директорий),
  51.      * начиная с заданной директории (startPath)
  52.      * @param startPath Начальная директория поиска
  53.      * @return Список (List) найденных объектов
  54.      * @throws java.lang.Exception если возникли ошибки в процессе поиска
  55.      */
  56.     public List findAll(String startPath) throws Exception {
  57.         return find(startPath, "", ALL);
  58.     }
  59.  
  60.     /**
  61.      * Этот метод выполняет поиск объектов (файлов и директорий),
  62.      * которые соответствуют заданному регулярному выражению (mask),
  63.      * начиная с заданной директории (startPath)
  64.      * @param startPath Начальная директория поиска
  65.      * @param mask регулярное выражение, которому должны соответствовать
  66.      * имена найденный объектов
  67.      * @throws java.lang.Exception если возникли ошибки в процессе поиска
  68.      * @return Список (List) найденных объектов
  69.      */
  70.     public List findAll(String startPath, String mask)
  71.             throws Exception {
  72.         return find(startPath, mask, ALL);
  73.     }
  74.  
  75.     /**
  76.      * Этот метод выполняет поиск всех файлов,
  77.      * начиная с заданной директории (startPath)
  78.      * @param startPath Начальная директория поиска
  79.      * @return Список (List) найденных объектов
  80.      * @throws java.lang.Exception если возникли ошибки в процессе поиска
  81.      */
  82.     public List findFiles(String startPath)
  83.             throws Exception {
  84.         return find(startPath, "", FILES);
  85.     }
  86.  
  87.     /**
  88.      * Этот метод выполняет поиск файлов,
  89.      * которые соответствуют заданному регулярному выражению (mask),
  90.      * начиная с заданной директории (startPath)
  91.      * @param startPath Начальная директория поиска
  92.      * @param mask регулярное выражение, которому должны соответствовать
  93.      * имена найденный объектов
  94.      * @throws java.lang.Exception если возникли ошибки в процессе поиска
  95.      * @return Список (List) найденных объектов
  96.      */
  97.     public List findFiles(String startPath, String mask)
  98.             throws Exception {
  99.         return find(startPath, mask, FILES);
  100.     }
  101.  
  102.     /**
  103.      * Этот метод выполняет поиск всех директорий (папок),
  104.      * начиная с заданной директории (startPath)
  105.      * @param startPath Начальная директория поиска
  106.      * @return Список (List) найденных объектов
  107.      * @throws java.lang.Exception если возникли ошибки в процессе поиска
  108.      */
  109.     public List findDirectories(String startPath)
  110.             throws Exception {
  111.         return find(startPath, "", DIRECTORIES);
  112.     }
  113.  
  114.     /**
  115.      * Этот метод выполняет поиск директорий (папок),
  116.      * которые соответствуют заданному регулярному выражению (mask),
  117.      * начиная с заданной директории (startPath)
  118.      * @param startPath Начальная директория поиска
  119.      * @param mask регулярное выражение, которому должны соответствовать
  120.      * имена найденный объектов
  121.      * @throws java.lang.Exception если возникли ошибки в процессе поиска
  122.      * @return Список (List) найденных объектов
  123.      */
  124.     public List findDirectories(String startPath, String mask)
  125.             throws Exception {
  126.         return find(startPath, mask, DIRECTORIES);
  127.     }
  128.  
  129.     /**
  130.      * Возвращает суммарный размер найденных файлов
  131.      * @return размер найденных файлов (байт)
  132.      */
  133.     public long getDirectorySize() {
  134.         return totalLength;
  135.     }
  136.  
  137.     /**
  138.      * Возвращает общее количество найденных файлов
  139.      * @return количество найденных файлов
  140.      */
  141.     public long getFilesNumber() {
  142.         return filesNumber;
  143.     }
  144.  
  145.     /**
  146.      * Возвращает общее количество найденных директорий (папок)
  147.      * @return количество найденных директорий (папок)
  148.      */
  149.     public long getDirectoriesNumber() {
  150.         return directoriesNumber;
  151.     }
  152.  
  153.     /*
  154.     Проверяет, соответствует ли имя файла заданному
  155.     регулярному выражению. Возвращает true, если найденный
  156.     объект соответствует регулярному выражению, false - в
  157.     противном случае.
  158.     */
  159.     private boolean accept(String name) {
  160.         //если регулярное выражение не задано…
  161.         if(p == null) {
  162.             //…значит объект подходит
  163.             return true;
  164.         }
  165.         //создаем Matcher
  166.         m = p.matcher(name);
  167.         //выполняем проверку
  168.         if(m.matches()) {
  169.             return true;
  170.         }
  171.         else {
  172.             return false;
  173.         }
  174.     }
  175.  
  176.     /*
  177.     Этот метод выполняет начальные установки поиска.
  178.     Затем вызывает метод search для выполнения поиска.
  179.     */
  180.     private List find(String startPath, String mask, int objectType)
  181.             throws Exception {
  182.         //сбрасываем переменную стоп, т.к. она могла быть установлена
  183.         //в true после остановки предыдущего поиска
  184.         stop = false;
  185.         //проверка параметров
  186.         if(startPath == null || mask == null) {
  187.             throw new Exception("Ошибка: не заданы параметры поиска");
  188.         }
  189.         File topDirectory = new File(startPath);
  190.         if(!topDirectory.exists()) {
  191.             throw new Exception("Ошибка: указанный путь не существует");
  192.         }
  193.         //если задано регулярное выражение, создаем Pattern
  194.         if(!mask.equals("")) {
  195.             p = Pattern.compile(mask,
  196.                     Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
  197.         }
  198.         //обнуляем все счетчики
  199.         filesNumber = 0;
  200.         directoriesNumber = 0;
  201.         totalLength = 0;
  202.         //создаем список результатов
  203.         ArrayList res = new ArrayList(100);
  204.  
  205.         //уведомляем все зарегистрированные (с помощью метода addListener)
  206.         //объекты о начале поиска
  207.         if(listeners != null) {
  208.             for(int i = 0; i < listeners.size(); i++) {
  209.                 ((SearchListener)listeners.get(i)).onSearchStart();
  210.             }
  211.         }
  212.  
  213.         //выполняем поиск
  214.         search(topDirectory, res, objectType);
  215.  
  216.         //уведомляем все зарегистрированные (с помощью метода addListener)
  217.         //объекты о завершении поиска
  218.         if(listeners != null) {
  219.             for(int i = 0; i < listeners.size(); i++) {
  220.                 ((SearchListener)listeners.get(i)).onSearchEnd();
  221.             }
  222.         }
  223.  
  224.         //присваиваем null шаблону, т.к. при следующем вызове find…
  225.         //регулярное выражение может быть не задано
  226.         p = null;
  227.         //возвращаем результат
  228.         return res;
  229.     }
  230.  
  231.     /*
  232.     Этот метод выполняет поиск объектов заданного типа.
  233.     Если, в процессе поиска, встречает вложенную директорию
  234.     (папку), то рекурсивно вызывает сам себя.
  235.     Результаты поиска сохраняются в параметре res.
  236.     Текущая директория - topDirectory.
  237.     Тип объекта (файл или директория) - objectType.
  238.     */
  239.     private void search(File topDirectory, List res, int objectType) {
  240.         //если нужно остановить поиск…
  241.         if(stop == true) {
  242.             //… выходим
  243.             return;
  244.         }
  245.         //уведомляем все зарегистрированные (с помощью метода addListener)
  246.         //объекты о состоянии процесса поиска
  247.         if(listeners != null) {
  248.             for(int i = 0; i < listeners.size(); i++) {
  249.                 ((SearchListener)listeners.get(i)).onSearchProgressChange(
  250.                         totalLength, filesNumber, directoriesNumber);
  251.             }
  252.         }
  253.         //получаем список всех объектов в текущей директории
  254.         File[] list = topDirectory.listFiles();
  255.         //просматриваем все объекты по-очереди
  256.         for(int i = 0; i < list.length; i++) {
  257.             //если это директория (папка)…
  258.             if(list[i].isDirectory()) {
  259.                 //…выполняем проверку на соответствие типу объекта
  260.                 // и регулярному выражению…
  261.                 if(objectType != FILES && accept(list[i].getName())) {
  262.                     //…добавляем текущий объект в список результатов,
  263.                     //и обновляем значения счетчиков
  264.                     directoriesNumber++;
  265.                     res.add(list[i]);
  266.                 }
  267.                 //выполняем поиск во вложенных директориях
  268.                 search(list[i], res, objectType);
  269.             }
  270.             //если это файл
  271.             else {
  272.                 //…выполняем проверку на соответствие типу объекта
  273.                 // и регулярному выражению…
  274.                 if(objectType != DIRECTORIES && accept(list[i].getName())) {
  275.                     //…добавляем текущий объект в список результатов,
  276.                     //и обновляем значения счетчиков
  277.                     filesNumber++;
  278.                     totalLength += list[i].length();
  279.                     res.add(list[i]);
  280.                 }
  281.             }
  282.         }
  283.     }
  284.  
  285.     /**
  286.      * Этот метод преденазначен для добавления объекта, который нужно
  287.      * уведемлять о состоянии процесса поиска
  288.      */
  289.     public void addListener(SearchListener listener) {
  290.         //Если список объектов не создан, то создаем его
  291.         if(listeners == null) {
  292.             //начальный размер устанавливаем равным единице, т.к. во
  293.             //многих случаях добавляется только один объект
  294.             listeners = new ArrayList(1);
  295.         }
  296.         //добавляем объект
  297.         listeners.add(listener);
  298.     }
  299.  
  300.     /**
  301.      * Этот метод останавливает процесс поиска
  302.      */
  303.     public void stopSearch() {
  304.         stop = true;
  305.     }
  306. }

Несколько слов об интерфейсе SearchListener. Его должны реализовать объекты, которые хотят получать уведомления о состоянии процесса поиска. В интерфейсе объявлены три метода. onSearchStart() – вызывается объектом класса FileFinder в начале поиска. onSearchProgressChange – вызывается в начале обработки каждой новой папки, в его параметрах передаются: общий размер найденных файлов, количество найденный файлов, количество просмотренных папок. Вызов метода onSearchEnd() указывает на завершение поиска.

Code (java)
  1. /*
  2. * SearchListener.java
  3. *
  4. * Created on 16 Октябрь 2006 г., 20:15
  5. *
  6. */
  7.  
  8. package searchtools;
  9.  
  10. /**
  11. * Этот интерфейс должны реализовать все классы, которые хотят
  12. * следить за состоянием процесса поиска, который выполняется
  13. * классом FileFinder
  14. * @author Стаценко Владимир
  15. * http://www.vova-prog.narod.ru
  16. */
  17. public interface SearchListener {
  18.     /** Этот метод вызывается перед началом поиска
  19.      */
  20.     public void onSearchStart();
  21.  
  22.     /**
  23.      * Этот метод вызывается в процессе поиска. В его
  24.      * параметрах передается информация о количестве
  25.      * найденных объектов, их размере и т.п.
  26.      *
  27.      * @param totalLength общий размер найденных файлов
  28.      * @param filesNumber общее количество найденных файлов
  29.      * @param directoriesNumber общее количество просмотренных директорий
  30.      */
  31.     public void onSearchProgressChange(long totalLength,
  32.             long filesNumber, long directoriesNumber);
  33.  
  34.     /** Этот метод вызывается в конце поиска
  35.      */
  36.     public void onSearchEnd();
  37. }

Страницы: 1 2 3 4 5

Понравилась статья? Подпишитесь на продолжение rss link !

]]>

Добавьте эту страницу в google.com