Чтение онлайн

ЖАНРЫ

Философия Java3

Эккель Брюс

Шрифт:

Stri ng[] list. продолжение & if(args length == 0)

list = path listO.

else

list = path list(new Di rFi1ter(args[0])): Arrays.sort(1i st, Stri ng.CASE_INSENSITIVE_ORDER); for(String dirltem . list)

System out println(dirltem);

class DirFiIter implements FilenameFilter { private Pattern pattern, public Di rFilter(String regex) {

pattern = Pattern.compile(regex);

}

public boolean accept(File dir. String name) { return pattern.matcher(name).matchesО;

}

} /* Output. DirectoryDemo.java DirList.java DirList2.java Di rLi st3.java *///:-

Заметьте,

что аргумент метода filter должен быть неизменным (final). Это необходимо для того, чтобы внутренний класс смог получить к нему доступ даже за пределами области определения аргумента.

Несомненно, структура программы улучшилась хотя бы потому, что объект FilenameFilter теперь неразрывно связан с внешним классом DirList2. Впрочем, можно сделать следующий шаг и определить безымянный внутренний класс как аргумент метода list, в результате чего программа станет еще более компактной:

//: io/Dirl_ist3.java

// Создание безымянного внутреннего класса "на месте".

// {Параметры: "D.*\.java"}

import java.util.regex.*;

import java.io.*;

import java.util.*;

public class DirList3 {

public static void main(final String[] args) { File path = new File(V); String[] list; if(args.length == 0)

list = path.listO;

else

list = path.list(new FilenameFilterО {

private Pattern pattern = Pattern.compile(args[0]); public boolean accept(File dir, String name) { return pattern.matcher(name).matches;

}

}):

Arrays.sort(1i st. Stri ng.CASE_INSENSITIVE_ORDER); for(String dirltem : list)

System out println(dirltem).

}

} /* Output. DirectoryDemo.java DirList java DirList2.java DirList3.java */// ~

На этот раз неизменным (final) объявлен аргумент метода main, так как безымянный внутренний класс использует параметр командной строки (args[0]) напрямую.

Именно так безымянные внутренние классы позволяют быстро создать «одноразовый» класс, полезный только для решения одной конкретной задачи. Одно из преимуществ такого подхода состоит в том, что весь код, решающий некоторую задачу, находится в одном месте. С другой стороны, полученный код не слишком хорошо читается, поэтому при их использовании необходимо действовать осмотрительно.

Проверка существования и создание каталогов

Класс File не ограничивается представлением существующих файлов или каталогов, он способен на большее. Он также может использоваться для создания нового каталога или даже дерева каталогов, если последние не существуют. Можно также узнать свойства файлов (размер, дату последнего изменения, режим чтения (записи)), определить, файл или каталог представляет объект File, удалить файл. Следующая программа демонстрирует некоторые методы класса File (за полной информацией обращайтесь к документации JDК, доступной для загрузки с сайта java.sun.com):

//: io/MakeDirectories.java // Использование класса File для создания // каталогов и выполнения операций с файлами. // {Параметры: MakeDirectoriesTest} import java io.-*;

public class MakeDirectories {

private static void usageO { System.err.printl n(

,,Иcпoльзoвaниe:MakeDirectories путь1 ...\n" + "Создает все пути\п" +

"Иcпoльзoвaниe:MakeDirectories -d путь1 ...\n" + "Удаляет все пути\п" +

"Использование:Маке01rectories -г путь1 путь2\п" + "Переименовывает путь1 в путь2\п"; System.exit(l),

}

private static void fileDataCFile f) { System.out.printl n(

"Полное

имя: " + f.getAbsolutePath +

"\n доступно для чтения: " + f.canReadO +

"\n доступно для записи: " + f.canWriteO +

"\п имя файла getNameO. " + f.getNameO +

"\n родительский каталог getParentO: " + f.getParentO +

"\п путь getPathO " + f getPathO + "\п размер " + f length О + "\n последнее изменение " + f lastModifiedO). if(f isFileO)

System out printin("Это файл"), else if(f isDirectoryO)

System out println("3io каталог").

}

public static void main(String[] args) { if(args length < 1) usageO, if(args[0] equals("-r")) {

if(args length != 3) usageO. File

old = new File(args[l]). rname = new File(args[2]). old.renameTo(rname); fileData(old). fileDataCrname). return. // Выход из метода main

}

int count = 0; boolean del = false. if(args[0] equals("-d")) { count++, del = true.

}

count--;

while(++count < args length) {

File f = new File(args[count]). if(f existsO) {

System out println(f + " существует"); if(del) {

System out рппШСудаление " + f); f deleted;

else { // He существует i f(!del) {

f.mkdirsO.

System.out ргШ1п("создано " + f);

fileData(f).

} /* Output:

создано MakeDirectoriesTest

Полное имя: d'\aaa-TIJ4\code\io\MakeDirectoriesTest доступно для чтения- true доступно для записи, true имя файла getNameO MakeDirectoriesTest родительский каталог getParentO null путь getPathO MakeDirectoriesTest размер 0

последнее изменение 1101690308831 Это каталог *///.-

В методе fileData продемонстрированы различные методы, предназначенные для получения информации о файлах и каталогах.

Сначала в методе main вызывается метод renameTo, который позволяет переименовывать (или перемещать) файлы, используя для этого второй аргумент — еще один объект File, который указывает на новое местоположение или имя.

Если вы поэкспериментируете с этой программой, то увидите, что создать пути произвольной сложности очень просто, поскольку всю работу за вас фактически делает метод mkdirs.

Ввод и вывод

В библиотеках ввода/вывода часто используется абстрактное понятие потока (stream) — произвольного источника или приемника данных, который способен производить или получать некоторую информацию. Поток скрывает детали низкоуровневых процессов, происходящих с данными непосредственно в устройствах ввода/вывода.

Классы библиотеки ввода/вывода Java разделены на две части — одни осуществляют ввод, другие вывод. В этом можно убедиться, просмотрев документацию JDK. Все классы, производные от базовых классов InputStream или Reader, имеют методы с именами read для чтения одиночных байтов или массива байтов. Аналогично, все классы, производные от базовых классов OutputStream или Writer, имеют методы с именами write для записи одиночных байтов или массива байтов. Впрочем, вы вряд ли станете использовать эти методы напрямую — они в основном предназначены для других классов, предоставляющих более полные возможности. Таким образом, заключение объекта-потока в один класс — занятие довольно неэффективное, обычно несколько объектов «наслаиваются» друг на друга для получения необходимой функциональности. Необходимость построения потока на основе нескольких объектов — главная причина трудностей в освоении библиотеки ввода/вывода Java.

Поделиться с друзьями: