Внимание! Это сайт переехал на www.simplecoding.org
Новые возможности
Структура программы
Управление поиском
Изменения в исходниках библиотеки
Создание графического интерфейса
Скачать
Изменения в исходниках библиотеки
Как я уже говорил, для поиска файлов мы будем использовать библиотеку, разработанную в предыдущих статьях. Но нам нужно внести в неё небольшие изменения, которые позволят управлять процессом поиска, и использовать библиотеку в многопоточных приложениях.
Сделать это не сложно. Во-первых, в классе FileFinder мы добавляем переменную stop и метод stopSearch(), с помощь которых мы сможем прервать поиск. Во-вторых, создаём в библиотеке новый интерфейс SearchListener, а для его поддержки, в класс FileFinder мы добавляем список объектов (listeners), которые будут получать уведомления о ходе поиска, и метод addListener(), с помощью которого можно регистрировать новые объекты.
Посмотрим на исходный код класса FileFinder. Жирным шрифтом отмечены добавленные участки кода.
/* * FileFinder.java * * Created on 13 Сентябрь 2006 г., 19:50 */ package searchtools; import java.io.File; import java.io.FilenameFilter; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Этот класс предназначен для поиска файлов * * @author Стаценко Владимир * http://www.vova-prog.narod.ru */ public class FileFinder { //классы для работы с регулярными выражениями private Pattern p = null; private Matcher m = null; //общий размер найденных файлов private long totalLength = 0; //общее количество найденных файлов private long filesNumber = 0; //общее количество просмотренных директорий private long directoriesNumber = 0; //константы для определения объектов, которые нужно найти private final int FILES = 0; private final int DIRECTORIES = 1; private final int ALL = 2; //список с объектами, которые должны быть уведомлены о состоянии поиска private List listeners = null; //используется для остановки поиска private boolean stop = false; /** Создает новые экземпляры FileFinder */ public FileFinder() { } /** * Этот метод выполняет поиск всех объектов (файлов и директорий), * начиная с заданной директории (startPath) * @param startPath Начальная директория поиска * @return Список (List) найденных объектов * @throws java.lang.Exception если возникли ошибки в процессе поиска */ public List findAll(String startPath) throws Exception { return find(startPath, "", ALL); } /** * Этот метод выполняет поиск объектов (файлов и директорий), * которые соответствуют заданному регулярному выражению (mask), * начиная с заданной директории (startPath) * @param startPath Начальная директория поиска * @param mask регулярное выражение, которому должны соответствовать * имена найденный объектов * @throws java.lang.Exception если возникли ошибки в процессе поиска * @return Список (List) найденных объектов */ public List findAll(String startPath, String mask) throws Exception { return find(startPath, mask, ALL); } /** * Этот метод выполняет поиск всех файлов, * начиная с заданной директории (startPath) * @param startPath Начальная директория поиска * @return Список (List) найденных объектов * @throws java.lang.Exception если возникли ошибки в процессе поиска */ public List findFiles(String startPath) throws Exception { return find(startPath, "", FILES); } /** * Этот метод выполняет поиск файлов, * которые соответствуют заданному регулярному выражению (mask), * начиная с заданной директории (startPath) * @param startPath Начальная директория поиска * @param mask регулярное выражение, которому должны соответствовать * имена найденный объектов * @throws java.lang.Exception если возникли ошибки в процессе поиска * @return Список (List) найденных объектов */ public List findFiles(String startPath, String mask) throws Exception { return find(startPath, mask, FILES); } /** * Этот метод выполняет поиск всех директорий (папок), * начиная с заданной директории (startPath) * @param startPath Начальная директория поиска * @return Список (List) найденных объектов * @throws java.lang.Exception если возникли ошибки в процессе поиска */ public List findDirectories(String startPath) throws Exception { return find(startPath, "", DIRECTORIES); } /** * Этот метод выполняет поиск директорий (папок), * которые соответствуют заданному регулярному выражению (mask), * начиная с заданной директории (startPath) * @param startPath Начальная директория поиска * @param mask регулярное выражение, которому должны соответствовать * имена найденный объектов * @throws java.lang.Exception если возникли ошибки в процессе поиска * @return Список (List) найденных объектов */ public List findDirectories(String startPath, String mask) throws Exception { return find(startPath, mask, DIRECTORIES); } /** * Возвращает суммарный размер найденных файлов * @return размер найденных файлов (байт) */ public long getDirectorySize() { return totalLength; } /** * Возвращает общее количество найденных файлов * @return количество найденных файлов */ public long getFilesNumber() { return filesNumber; } /** * Возвращает общее количество найденных директорий (папок) * @return количество найденных директорий (папок) */ public long getDirectoriesNumber() { return directoriesNumber; } /* Проверяет, соответствует ли имя файла заданному регулярному выражению. Возвращает true, если найденный объект соответствует регулярному выражению, false - в противном случае. */ private boolean accept(String name) { //если регулярное выражение не задано... if(p == null) { //...значит объект подходит return true; } //создаем Matcher m = p.matcher(name); //выполняем проверку if(m.matches()) { return true; } else { return false; } } /* Этот метод выполняет начальные установки поиска. Затем вызывает метод search для выполнения поиска. */ private List find(String startPath, String mask, int objectType) throws Exception { //сбрасываем переменную стоп, т.к. она могла быть установлена //в true после остановки предыдущего поиска stop = false; //проверка параметров if(startPath == null || mask == null) { throw new Exception("Ошибка: не заданы параметры поиска"); } File topDirectory = new File(startPath); if(!topDirectory.exists()) { throw new Exception("Ошибка: указанный путь не существует"); } //если задано регулярное выражение, создаем Pattern if(!mask.equals("")) { p = Pattern.compile(mask, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); } //обнуляем все счетчики filesNumber = 0; directoriesNumber = 0; totalLength = 0; //создаем список результатов ArrayList res = new ArrayList(100); //уведомляем все зарегистрированные (с помощью метода addListener) //объекты о начале поиска if(listeners != null) { for(int i = 0; i < listeners.size(); i++) { ((SearchListener)listeners.get(i)).onSearchStart(); } } //выполняем поиск search(topDirectory, res, objectType); //уведомляем все зарегистрированные (с помощью метода addListener) //объекты о завершении поиска if(listeners != null) { for(int i = 0; i < listeners.size(); i++) { ((SearchListener)listeners.get(i)).onSearchEnd(); } } //присваиваем null шаблону, т.к. при следующем вызове find... //регулярное выражение может быть не задано p = null; //возвращаем результат return res; } /* Этот метод выполняет поиск объектов заданного типа. Если, в процессе поиска, встречает вложенную директорию (папку), то рекурсивно вызывает сам себя. Результаты поиска сохраняются в параметре res. Текущая директория - topDirectory. Тип объекта (файл или директория) - objectType. */ private void search(File topDirectory, List res, int objectType) { //если нужно остановить поиск... if(stop == true) { //... выходим return; } //уведомляем все зарегистрированные (с помощью метода addListener) //объекты о состоянии процесса поиска if(listeners != null) { for(int i = 0; i < listeners.size(); i++) { ((SearchListener)listeners.get(i)).onSearchProgressChange( totalLength, filesNumber, directoriesNumber); } } //получаем список всех объектов в текущей директории File[] list = topDirectory.listFiles(); //просматриваем все объекты по-очереди for(int i = 0; i < list.length; i++) { //если это директория (папка)... if(list[i].isDirectory()) { //...выполняем проверку на соответствие типу объекта // и регулярному выражению... if(objectType != FILES && accept(list[i].getName())) { //...добавляем текущий объект в список результатов, //и обновляем значения счетчиков directoriesNumber++; res.add(list[i]); } //выполняем поиск во вложенных директориях search(list[i], res, objectType); } //если это файл else { //...выполняем проверку на соответствие типу объекта // и регулярному выражению... if(objectType != DIRECTORIES && accept(list[i].getName())) { //...добавляем текущий объект в список результатов, //и обновляем значения счетчиков filesNumber++; totalLength += list[i].length(); res.add(list[i]); } } } } /** * Этот метод преденазначен для добавления объекта, который нужно * уведемлять о состоянии процесса поиска */ public void addListener(SearchListener listener) { //Если список объектов не создан, то создаем его if(listeners == null) { //начальный размер устанавливаем равным единице, т.к. во //многих случаях добавляется только один объект listeners = new ArrayList(1); } //добавляем объект listeners.add(listener); } /** * Этот метод останавливает процесс поиска */ public void stopSearch() { stop = true; } }
Несколько слов об интерфейсе SearchListener. Его должны реализовать объекты, которые хотят получать уведомления о состоянии процесса поиска. В интерфейсе объявлены три метода. onSearchStart() – вызывается объектом класса FileFinder в начале поиска. onSearchProgressChange – вызывается в начале обработки каждой новой папки, в его параметрах передаются: общий размер найденных файлов, количество найденный файлов, количество просмотренных папок. Вызов метода onSearchEnd() указывает на завершение поиска.
Предыдущий раздел Читать дальше/* * SearchListener.java * * Created on 16 Октябрь 2006 г., 20:15 * */ package searchtools; /** * Этот интерфейс должны реализовать все классы, которые хотят * следить за состоянием процесса поиска, который выполняется * классомFileFinder
* @author Стаценко Владимир * http://www.vova-prog.narod.ru */ public interface SearchListener { /** Этот метод вызывается перед началом поиска */ public void onSearchStart(); /** * Этот метод вызывается в процессе поиска. В его * параметрах передается информация о количестве * найденных объектов, их размере и т.п. * * @param totalLength общий размер найденных файлов * @param filesNumber общее количество найденных файлов * @param directoriesNumber общее количество просмотренных директорий */ public void onSearchProgressChange(long totalLength, long filesNumber, long directoriesNumber); /** Этот метод вызывается в конце поиска */ public void onSearchEnd(); }