Ответы на вопросы по ревью 4. Java io. Ключевым понятием здесь является понятие потока
Скачать 1.93 Mb.
|
Добавление атрибутов и полезных интерфейсовИспользование многослойных объектов для динамического и прозрачного добавления ответственности индивидуальным объектам, называется шаблоном декорации. (Шаблоны [57] являются предметом обсуждения Thinking in Patterns with Java, доступной на www.BruceEckel.com.) Шаблон декорации определяет, что все объекты, которые крутятся вокруг вашего начального объекта, имеют один и тот же интерфейс. Это делает основное использование декораторов прозрачным — вы посылаете объекту одни и те же с сообщения не зависимо от того, был он декорирован или нет. Это причина существования “фильтрующих” классов в библиотеке ввода/вывода в Java: абстрактный “фильтрующий” класс - это базовый класс для всех декораторов. (Декоратор должен иметь такой же интерфейс, что и объект, который он декорирует, но декоратор так же может расширить интерфейс, что случается в некоторых “фильтрующих” классах. Декорирование часто используется, когда простое использование подклассов в результате приводит к большому числу подклассов, способных удовлетворить каждую возможную необходимую комбинацию, что становится непрактично. Библиотека ввода/вывода Java требует много различных комбинаций особенностей, которые являются причиной использования шаблона декоратора. Однако для шаблона декоратора есть препятствие. Декораторы дают вам много больше гибкости, когда вы пишите программу (так как вы можете легко смешивать и сравнивать атрибуты), но они привносят сложность в ваш код. Причина того, что библиотека Java неудобна в использовании, состоит в том, что вы должны создавать много классов — “центральные” типы ввода/вывода, плюс все декораторы — для того, чтобы создать единственный объект ввода/вывода, который вам нужен. К классам, обеспечивающим интерфейс декоратора для управления определенным InputStream'>InputStream или OutputStream, относятся FilterInputStream и FilterOutputStream — которые не имеют интуитивно понятных имен. FilterInputStream и FilterOutputStream являются абстрактными классами, наследованными от базовых классов библиотеки ввода/вывода InputStream и OutputStream, которые являются ключевым требованием декоратора (так как он обеспечивает общий интерфейс для всех объектов, которые будут декорироваться). Чтение из InputStream с помощью FilterInputStreamКлассы FilterInputStream совершают две значительные вещи. DataInputStream позволяет вам читать различные типы примитивных данных, наряду с объектами типа String. (Все методы начинаются со слова “read”, например: readByte( ), readFloat( ), и т.п.) Таким образом, наряду со своим компаньоном DataOutputStream, это позволяет вам перемещать примитивные данные из одного места в другое через поток. Эти “места” определяются классами в таблице 11-1. Оставшиеся классы изменяют способ внутреннего поведения InputStream: будет ли он буферизированный или нет, будет ли он хранить историю прочитанных строк (позволяя вам спрашивать номер строки или множества номеров строк), и сможете ли вы поместить назад единичный символ. Последние два класса выглядят так, как будто они предназначены для поддержки работы компилятора (то есть, они были добавлены для поддержки конструкций Java компилятора), так что вы, вероятно, не захотите использовать их в обычном программировании. Вероятно, вам необходимо будет буферизировать ваш ввод почти каждый раз, в зависимости от устройства ввода/вывода, к которому вы подсоединяетесь, так что имеет больше смысла для библиотеки ввода/вывода сделать особый случай (или простой вызов метода) для не буферизированного ввода, в отличие от буферизированного ввода. Таблица 11-3. Типы FilterInputStream
Запись в OutputStream с помощью FilterOutputStreamДополнением к DataInputStream является OutputStream'>DataOutputStream, который форматирует каждый из примитивных типов и объекты String в поток, таким образом, которым любой DataInputStream на любой машине смог бы прочесть его. Все методы начинаются со слова “write”, например writeByte( ), writeFloat( ) и т.п. Изначальное предназначение PrintStream'>PrintStream было в печати всех примитивных типов данных и объектов String в удобочитаемом формате. Он отличается от DataOutputStream, чья цель состоит в помещении элементов данных в поток таким способом, чтобы DataInputStream мог без труда реконструировать их. Двумя важнейшими методами PrintStream являются print( ) и println( ), которые перегружены для печати всех различных типов. Различия между print( ) и println( ) в том, что последний метод добавляет символ новой строки, когда завершен вывод. PrintStream может быть проблематичным, поскольку он ловит все IOException (вы должны явно проверять статус ошибки с помощью checkError( ), который возвращает true, если возникла ошибка). Так же PrintStream не интернацианализован полностью и не обрабатывает переводы строки платформонезависимым способом (эти проблемы решаются с помощью PrintWriter). BufferedOutputStream является модификатором и говорит потоку, что нужно использовать буферизацию, так что вы не получите физической записи при каждой записи в поток. Вы, вероятно, всегда захотите использовать это с файлами, и, возможно, при консольном вводе/выводе. Таблица 11-4. Типы FilterOutputStream
|