Рейтинговые книги
Читем онлайн Философия Java3 - Брюс Эккель

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 96 97 98 99 100 101 102 103 104 ... 132

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-TIJ4codeioMakeDirectoriesTest доступно для чтения- 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.

Классы ввода/вывода удобно разделить по категориям, в зависимости от их функций. В Java 1.0 разработчики решили, что все, связанное с вводом данных, должно быть производным от базового класса InputStream, а все, имеющее отношение к выводу данных, — от класса OutputStream.

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

Типы InputStream

Назначение базового класса InputStream — представлять классы, которые получают данные из различных источников. Такими источниками могут быть:

• массив байтов;

• строка (String);

• файл;

• «канал» (pipe): данные помещаются с одного «конца» и извлекаются с другого;

• последовательность различных потоков, которые можно объединить в одном потоке;

• другие источники (например, подключение к Интернету).

С каждым из перечисленных источников связывается некоторый подкласс базового класса InputStream (табл. 16.1). Существует еще класс FilterlnputStream, который также является производным классом InputStream и представляет собой основу для классов-«надстроек», наделяющих входные потоки полезными свойствами и интерфейами. Его мы обсудим чуть позже.

Таблица 16.1. Разновидности входных потоков InputStream

Класс Назначение Аргументы конструктора,

порядок применения

Позволяет использовать буфер в памяти (массив байтов) в качестве источника данных для входного потока

ByteArraylnputStream

StringBufferlnputStream

FilelnputStream

PipedlnputStream

SequencelnputStream

FilterlnputStream

Превращает строку (String) во входной поток данных InputStream

Для чтения информации из файла

Производит данные, записываемые в соответствующий выходной поток PipedOutputStream. Реализует понятие канала

Сливает два или более потока InputStream в единый поток

Абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства

Буфер, из которого читаются байты. Как источник данных. Присоедините поток к классу FilterlnputStream, чтобы получить расширенные возможности

Строка. Лежащая в основе класса реализация на самом деле использует класс StringBuffer. Как источник данных. Присоедините поток к классу FilterlnputStream, чтобы получить расширенные возможности

Строка (String) с именем файла или объекты File и FileDescriptor. Как источник данных. Присоедините поток к классу FilterlnputStream, чтобы получить расширенные возможности

Объект PipedOutputStream. Как источник данных в многозадачном окружении. Присоедините поток к классу FilterlnputStream, чтобы получить расширенные возможности Два объекта-потока InputStream или перечисление Enumeration для контейнера, в котором содержатся все потоки.

Как источник данных. Присоедините поток к классу FilterlnputStream, чтобы получить расширенные возможности См. табл. 16.3

Типы OutputStream

В данную категорию (табл. 16.2) попадают классы, определяющие, куда направляются ваши данные: в массив байтов (но не напрямую в String; предполагается, что вы сможете создать их из массива байтов), в файл или в канал.

Вдобавок класс FilterOutputStream предоставляет базовый класс для клас-сов-«надстроек», которые способны наделять существующие потоки новыми полезными атрибутами и интерфейсами. Подробности мы отложим на потом.

Таблица 16.2. Разновидности выходных потоков OutputStream

Аргументы конструктора, порядок применения

Класс

Назначение

ByteArrayOutputStream Создает буфер в памяти. Все

данные, посылаемые в этот поток, размещаются в созданном буфере

FileOutputStream

PipedOutputStream

FilterOutputStream

Отправка данных в файл на диске

Все данные, записываемые в поток, автоматически появляются как входные данные в ассоциированном потоке PipedlnputStream. Реализует понятие канала

Абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства

Начальный размер буфера (не обязательно). Задает приемник данных. Присоедините поток к объекту FilterOutputStream, чтобы получить расширенные возможности Строка с именем файла или объекты File или FileDescriptor. Задает приемник данных. Присоедините этот поток к объекту FilterOutputStream, чтобы получить расширенные возможности Объект PipedlnputStream. Задает приемник данных в многозадачном окружении. Присоедините этот поток к объекту FilterOutputStream, чтобы получить расширенные возможности См. табл. 16.4

1 ... 96 97 98 99 100 101 102 103 104 ... 132
На этой странице вы можете бесплатно читать книгу Философия Java3 - Брюс Эккель бесплатно.
Похожие на Философия Java3 - Брюс Эккель книги

Оставить комментарий