Система ввода-вывода в Java. Работа с файлами

Обычно часть вычислительной платформы, которая отвечает за обмен данным, так и называется - система ввода/вывода. В Java она представлена пакетом java.io (input/output). Реализация системы ввода/вывода осложняется не только широким спектром источников и получателей данных, но еще и различными форматами передачи информации. Ею можно обмениваться в двоичном представлении, символьном или текстовом с применением некоторой кодировки, или передавать числа в различных представлениях. Доступ к данным может потребоваться как последовательный (например, считывание HTML страницы), так и произвольный (сложная работа с несколькими частями одного файла). Зачастую для повышения производительности применяется буферизация. В Java для описания работы по вводу/выводу используется специальное понятие поток данных (stream). Поток данных связан с некоторым источником или приемником данных, способных получать или предоставлять информацию. Соответственно, потоки делятся на входные - читающие данные, и на выходные - передающие (записывающие) данные. Введение концепции stream позволяет отделить программу, обменивающуюся информацией одинаковым образом с любыми устройствами, от низкоуровневых операций с такими устройствами ввода/вывода.

В Java потоки естественным образом представляются объектами. Описывающие их классы как раз и составляют основную часть пакета java.io. Они довольно разнообразны и отвечают за различную функциональность. Все классы разделены на две части - одни осуществляют ввод данных, другие вывод.

Существующие стандартные классы помогают решить большинство типичных задач. Минимальной "порцией" информации является, как известно, бит, принимающий значение 0 или 1 (это понятие также удобно применять на самом низком уровне, где данные передаются электрическим сигналом; условно говоря, 1 представляется прохождением импульса, 0 - его отсутствием). Традиционно используется более крупная единица измерения байт, объединяющая 8 бит. Таким образом, значение, представленное 1 байтом, находится в диапазоне от 0 до 28-1=255, или, если использовать знак, от -128 до +127. Примитивный тип byte в Java в точности соответствует последнему, знаковому диапазону. Базовые, наиболее универсальные классы позволяют считывать и записывать информацию именно в виде набора байт. Чтобы их было удобно применять в различных задачах, java.io содержит также классы, преобразующие любые данные в набор байт.

Как и говорилось, все типы поделены на две группы.

InputStream - это базовый класс для потоков ввода, т.е. чтения. Соответственно, он описывает базовые методы для работы с байтовыми потоками данных. Эти методы необходимы всем классам, наследующимся от InputStream.

OutputStream - это базовый класс для потоков вывода.

В языке Java есть много классов для работы с файлами и прочими потоками ввода/вывода, они расположены в пакете java.io. Коротко рассмотрим некоторые из них.

Класс File. служит для получения информации о файлах и каталогах. Для создания объекта этого класса есть 3 конструктора, чаще всего используется следующий: File(String имя_файла) - создание объекта 'файл' по его имени в файловой системе

I. Следующие 5 классов используются для работы с двоичными файлами:

Класс FileInputStream(производный от InputStream)- простейший класс для потокового (последовательного) чтения данных из файла. Объект этого класса создается на основе объекта File или по имени файла в файловой системе, например, FileInputStream myfile = new FileInputStream("data.txt"); Для чтения данных используются методы - read()читает и возвращает один символ из файла; и read(byte [] массив) - читает и возвращает массив символов из файла. Для закрытия файла есть метод close, определенный в родительском классе InputStream.

Класс FileOutputStream (производный от OutputStream) - простейший класс для потокового (последовательного) вывода данных в файл. Объект этого класса создается на основе объекта File или по имени файла в файловой системе, например, FileOutputStream myfile = new FileOutputStream("data.txt"); Для записи данных используются методы: write(int символ) - печатает один символ в файл; и write(byte [] массив) - печатает массив байтов в файл. Для закрытия файла есть метод close, определенный в родительском классе OutputStream.

Класс DataInputStream (производный от InputStream) - простейший класс для потокового (последовательного) чтения данных стандартных типов из файла. Объект этого класса создается на основе объекта InputStream, т.е., например, DataInputStream myfile = new DataInputStream( new FileInputStream("data.txt")); Для всех стандартных типов данных определены методы: readInt(), readFloat(), readChar()и т.п. - читает значение указанного типа.

Класс DataOutputStream(производный от OutputStream) - простейший класс для потоковой (последовательной) записи данных стандартных типов в файл. Объект этого класса создается на основе объекта OutputStream, т.е., например, DataOutputStream myfile = new DataOutputStream( new FileOutputStream("data.txt")); Для всех стандартных типов данных определены методы: writeInt(int число), writeFloat(float число), writeChar(char символ), writeChars(String строка)и т.п. - печатает значение указанного типа.

Класс RandomAccessFile - класс для работы с файлами произвольного доступа, используется как для чтения, так и для записи. Объект этого класса cоздается на основе объекта File или по имени файла в файловой системе. Для всех стандартных типов данных определены методы: readInt(), readFloat(), readChar() т.п. - читает значение указанного типа; writeInt(int число), writeFloat(float число),writeChar(char символ),writeChars(String строка)и т.п. - печатает значение указанного типа.

II. Следующие 6 классов используются для работы с текстовыми файлами.

Классы InputStreamReader и OutputStreamWriter (производные от Reader и Writer) - простейшие классы для чтения/записи из/в текстовый файл. Объекты этих классов создаются на основе объектов InputStream и OutputStream. Например,

InputStreamReader myfile = new InputStreamReader( new FileInputStream("data.txt"));OutputStreamWriter myfile = new OutputStreamWriter( new FileOutputStream("data.txt"));

Оба класса имеют функцию getEncoding для получения текущей кодовой страницы (cp1251 - кодовая страница для русского Windows), а также конструкторы, которые позволяют задать нужную кодовую страницу в качестве второго параметра. Имеют только методы read и write для чтения/записи символа (строки символов).

Классы FileReader и FileWriter(производные от InputStreamWriter и OutputStreamWriter) - отличаются от InputStreamWriter и OutputStreamWriter тем, что объекты этих классов cоздаются на основе объекта File или по имени файла в файловой системе, т.е.

FileReader myfile = new FileReader("data.txt");FileWriter myfile = new FileWriter("data.txt");

а также не имеют конструктора с заданием кодовой страницы.

Классы BufferedReader и BufferedWriter (производные от Reader и Writer) - используются для буферизованного ввода-вывода данных, поэтому их использование более эффективно, чем, например, FileReader и FileWriter. Создаются на основе объектов Reader и Writer, например,

BufferedReader myfile = new BufferedReader ( new FileReader("data.txt"));BufferedWriter myfile = new BufferedWriter ( new FileWriter("data.txt"));

В классе BufferedReader определен метод readLine(), который позволяет читать строку символов.