Создание потоков, связанных с
файлами
Если вам нужно создать входной или выходной
поток, связанный с локальным файлом, следует
воспользоваться классами из библиотеки Java,
созданными на базе классов InputStream и OutputStream. Мы уже
кратко рассказывали об этих классах в разделе
"Классы Java для работы с потоками".
Однако методика использования перечисленных в
этом разделе классов может показаться довольно
странной.
В чем эта странность?
Говоря кратко, странность заключается в том,
что для создания потока вам необходимо
воспользоваться сразу несколькими классами, а не
одним, наиболее подходящим для решения
поставленной задачи, как это можно было бы
предположить.
Поясним сказанное на примере.
Пусть, например, нам нужен выходной поток для
записи форматированных данных (скажем, текстовых
строк класса String). Казалось бы, достаточно
создать объект класса DataOutputStream, - и дело сделано.
Однако не все так просто.
В классе DataOutputStream предусмотрен только один
конструктор, которому в качестве параметра
необходимо передать ссылку на объект класса
OutputStream:
public DataOutputStream(OutputStream out);
Что же касается конструктора класса OutputStream, то
он выглядит следующим образом:
public OutputStream();
Так как ни в том, ни в другом конструкторе не
предусмотрено никаких ссылок на файлы, то
непонятно, как с использованием только одних
классов OutputStream и DataOutputStream можно создать выходной
поток, связанный с файлом.
Что же делать?
Создание потока для форматированного обмена
данными
Оказывается, создание потоков, связанных с
файлами и предназначенных для форматированного
ввода или вывода, необходимо выполнять в
несколько приемов. При этом вначале необходимо
создать потоки на базе класса FileOutputStream или
FileInputStream, а затем передать ссылку на созданный
поток констркутору класса DataOutputStream или DataInputStream.
В классах FileOutputStream и FileInputStream предусмотрены
конструкторы, которым в качестве параметра
передается либо ссылка на объект класса File, либо
ссылка на объект класса FileDescriptor, либо, наконец,
текстовая строка пути к файлу:
public FileOutputStream(File file);
public FileOutputStream(
FileDescriptor fdObj);
public FileOutputStream(String name);
Таким образом, если вам нужен выходной поток
для записи форматированных данных, вначале вы
создаете поток как объект класса FileOutputStream. Затем
ссылку на этот объект следует передать
конструктору класса DataOutputStream. Полученный таким
образом объект класса DataOutputStream можно
использовать как выходной поток, записывая в
него форматированные данные.
Добавление буферизации
А что, если нам нужен не простой выходной поток,
а буферизованный?
Здесь нам может помочь класс BufferedOutputStream. Вот
два конструктора, предусмотренных в этом классе:
public BufferedOutputStream(
OutputStream out);
public BufferedOutputStream(
OutputStream out, int size);
Первый из них создает буферизованный выходной
поток на базе потока класса OutputStream, а второй
делает то же самое, но дополнительно позволяет
указать размер буфера в байтах.
Если вам нужно создать выходной буферизованный
поток для записи форматированных данных,
создание потока выполняется в три приема:
- создается поток, связанный с файлом, как объект
класса FileOutputStream;
- ссылка на этот поток передается конструктору
класса BufferedOutputStream, в результате чего создается
буферизованный поток, связанный с файлом;
- ссылка на буферизованный поток, созданный на
предыдущем шаге, передается конструктору класса
DataOutputStream, который и создает нужный поток
Вот фрагмент исходного текста программы,
который создает выходной буферизованный поток
для записи форматированных данных в файл с
именем output.txt:
DataOutputStream OutStream;
OutStream = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("output.txt")));
Аналогичным образом создается входной
буферизованный поток для чтения форматированных
данных из того же файла:
DataInputStream InStream;
InStream = new DataInputStream(
new BufferedInputStream(
new FileInputStream("output.txt")));
Исключения при создании потоков
При создании потоков на базе классов FileOutputStream и
FileInputStream могут возникать исключения FileNotFoundException,
SecurityException, IOException.
Исключение FileNotFoundException возникает при попытке
открыть входной поток данных для
несуществующего файла, то есть когда файл не
найден.
Исключение SecurityException возникает при попытке
открыть файл, для которого запрещен доступ.
Например, если файл можно только читать, а он
открывается для записи, возникнет исключение
SecurityException.
Если файл не может быть открыт для записи по
каким-либо другим причинам, возникает исключение
IOException.
|