В этой главе вы убедились в том, что язык Java предоставляет неплохую поддержку низкоуровневых массивов фиксированного размера. Такие массивы отдают предпочтение производительности перед гибкостью. В исходной версии Java низкоуровневые массивы фиксированного размера были абсолютно необходимы — не только потому, что проектировщики Java решили включить в язык примитивные типы (также по соображениям быстродействия), но и потому, что поддержка контейнеров в этой версии была крайне ограниченной.
В последующих версиях Java поддержка контейнеров была значительно улучшена. Сейчас контейнеры превосходят массивы во всех отношениях, кроме быстродействия, хотя производительность контейнеров была значительно улучшена. С добавлением автоматической упаковки и параметризации хранение примитивов в контейнерах требует меньших усилий и способствует дальнейшему переходу с низкоуровневых массивов на контейнеры. Так как параметризация открыла доступ к типизованным контейнерам, в этом отношении массивы тоже утратили исходные преимущества.
Как было показано в этой главе, параметризация плохо сочетается с контейнерами. Даже если вам удастся тем или иным способом заставить их работать вместе, во время компиляции вы будете получать предупреждения.
Все эти факторы показывают, что при программировании для последних версий Java следует отдавать предпочтение контейнерам перед массивами. На массивы следует переходить только при критичных требованиях по быстродействию — и только в том случае, если переход принесет ощутимую пользу.
Система
ввода/вывода
Java
Основная сложность состоит в том, что необходимо учесть все возможные ситуации. Это не только наличие множества источников и приемников данных, с которыми необходимо поддерживать связь (файлы, консоль, сетевые соединения), но и реализации различных форм этой связи (последовательный доступ, произвольный, буферизованный, двоичный, символьный, построчный, пословный и т. д.).
Разработчики библиотеки Java решили начать с создания огромного количества классов. Вообще говоря, в библиотеке ввода/вывода Java так много классов, что потеряться в них проще простого (парадоксально, но сама система ввода/вывода Java в действительности не нуждается в таком количестве классов). Потом, после выхода первой версии языка Java, в библиотеке ввода/вывода последовали значительные изменения: к ориентированным на посылку и прием
В этой главе мы познакомимся с различными классами, отвечающими за ввод/вывод в библиотеке Java, а также научимся использовать их.
Класс File
Перед тем как перейти к классам, которые осуществляют реальные запись и чтение данных, мы рассмотрим вспомогательные инструменты библиотеки, предназначенные для работы с файлами и каталогами.
Имя класса File весьма обманчиво: легко подумать, что оно всегда ссылается на файл, но это не так. Класс File может представлять как
Список каталогов
Предположим, вы хотите получить содержимое каталога. Объект File позволяет получить этот список двумя способами. Если вызвать метод list() без аргументов, то результатом будет полный список файлов и каталогов (точнее, их названий), содержащихся в данном каталоге. Но, если вам нужен ограниченный список — например, список всех файлов с расширением .java, — используйте «фильтр», то есть класс, который описывает критерии отбора объектов File.