Философия Java

Список директории


Предположим, вы хотите получить список директории. Объект File может выдать его двумя способами. Если вы вызовите list( ) без аргументов, вы получите полный список, содержащийся в объекте File. Однако если вы хотите ограничить список, например, если вы хотите получить все файлы с расширением .java, то вам нужно использовать “фильтр директории”, который является классом, который определяет, как использовать объект File для отображения.

Здесь приведен код примера. Обратите внимание, что результат без труда будет храниться (в алфавитном порядке) при использовании метода java.utils.Array.sort( ) и AlphabeticComparator, определенного в Главе 9:

//: c11:DirList.java

// Отображение списка директории.

import java.io.*; import java.util.*; import com.bruceeckel.util.*;

public class DirList { public static void main(String[] args) { File path = new File("."); String[] list; if(args.length == 0) list = path.list(); else list = path.list(new DirFilter(args[0])); Arrays.sort(list, new AlphabeticComparator()); for(int i = 0; i < list.length; i++) System.out.println(list[i]); } }

class DirFilter implements FilenameFilter { String afn; DirFilter(String afn) { this.afn = afn; } public boolean accept(File dir, String name) { // Получение информации о пути:

String f = new File(name).getName(); return f.indexOf(afn) != -1; } } ///:~

Класс DirFilter “реализует” interface FilenameFilter. Полезно посмотреть, насколько прост FilenameFilter interface:

public interface FilenameFilter { boolean accept(File dir, String name); }

Это говорит о том, что этот тип объекта должен обеспечивать метод, называемый accept( ). Главная цель создания этого класса заключается в обеспечении метода accept( ) для метода list( ), так как list( ) может выполнять “обратный вызов” accept( ) для определения, какое имя файла должно включаться в список. Эта техника часто называется обратным вызовом или иногда функтором (то есть, DirFilter - это функтор, потому что он выполняет работу по поддержанию метода) или Командой Заполнения. Потому что list( ) принимает объект FilenameFilter в качестве аргумента, это означает, что вы можете передать объект любого класса, который реализует FilenameFilter для выбора (даже во время выполнения) поведения метода list( ). Назначение обратного вызова заключается в обеспечении гибкого поведения кода.


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

Метод accept( ) должен принимать объект File, представляющий директорий, в котором находится определенный файл, а String содержит имя этого файла. Вы можете выбрать использовать или игнорировать любой из этих аргументов, но вы, вероятно, как минимум, должны использовать имя файла. Помните, что метод list( ) вызывает метод accept( ) для каждого имени файла в директории, чтобы проверить, какой из них должен быть включен — на это указывает тип boolean результата, возвращаемого accept( ).

Чтобы убедится, что элемент, с которым вы работаете, является всего лишь именем файла и не содержит информации о пути, все, что вам нужно сделать, это получить объект String и создать из него объект File, затем вызвать getName( ), который отсекает всю информацию о пути (платформонезависимым способом). Затем accept( ) использует метод indexOf( ) класса String, чтобы убедится, что искомая строка afn присутствует в любом месте имени файла. Если afn найдено в строке, возвращаемым значением является начальный индекс afn, а если не найдено, возвращаемым значением является -1. Имейте в виду, что это простой поиск строк и не имеет “глобальных” выражений подстановочных символов, таких как fo?.b?r*”, которые являются более сложными в реализации.

Метод list( ) возвращает массив. Вы можете опросить этот массив о его длине, а затем пройтись по нему, выбирая элементы массива. Эта способность легкого прохода по массиву вне методов и в методах является значительным улучшением по сравнению с поведением C и C++.


Содержание раздела