В Java предоставляется большое количество классов и методов, позволяющих читать и записывать данные в файлы. Разумеется, чаще всего приходится обращаться к файлам, хранящимся на дисках. В Java все файлы имеют байтовую организацию, и поэтому для побайтового чтения и записи данных в такие файлы предоставляются соответствующие методы. Следовательно, организовывать чтение и запись данных в файлы из байтовых потоков приходится довольно часто. Кроме того, для байтовых потоков ввода-вывода в файлы в Java разрешено создавать специальные оболочки в виде символьных объектов. Такие оболочки будут рассмотрены далее в этой главе.
Для того чтобы создать байтовый поток и связать его с файлом, следует воспользоваться классом FilelnputStream или FileOutputStream. А для открытия файла достаточно создать объект одного из этих классов, передав имя файла конструктору в качестве параметра. В открытый файл можно записывать данные или читать их из него. Ввод данных из файла
Файл открывается для ввода созданием объекта типа FilelnputStream. Для этой цели чаще всего используется приведенная ниже форма объявления конструктора данного класса. FilelnputStream(String имя_файла) throws FileNotFoundException
В качестве параметра этому конструктору передается имя_файла, который требуется открыть. Если указанный файл не существует, генерируется исключениеFileNotFoundException.
Для чтения данных из файла служит метод read . Ниже приведена форма объявления этого метода, которой мы будем пользоваться в дальнейшем, int read throws IOException
При каждом вызове метод read читает байт из файла и возвращает его как целочисленное значение. По достижении конца файла этот метод возвращает значение -1. При возникновении ошибки метод генерирует исключение IOException. Как видите, в этой форме метод read выполняет те же самые действия, что и одноименный метод для ввода данных с консоли.
Завершив операции с файлом, следует закрыть его с помощью метода close , общая форма объявления которого выглядит следующим образом: void close throws IOException
При закрытии файла освобождаются связанные с ним системные ресурсы, чтобы использовать их для работы с другим файлом. Если же файл не будет закрыт, могут произойти “утечки памяти” из-за того, что часть памяти остается выделенной для неиспользуемых ресурсов. Ниже приведен пример программы, где метод read используется для ввода содержимого текстового файла. Имя файла задается с помощью параметра в командной строке при запуске программы на выполнение. Полученные данные выводятся на экран. Обратите внимание на то, что ошибки ввода-вывода обрабатываются с помощью блока try/catch. /* Отображение текстового файла. При вызове этой программы следует указать имя файла, содержимое которого требуется просмотреть. Например, для вывода на экран содержимого файла TEST.TXT, в командной строке нужно указать следующее: java ShowFile TEST.TXT */ import java.io.*; class ShowFile { public static void main(String args[]) { int i; FilelnputStream fin; // Прежде всего следует убедиться, что файл был указан, if(args.length != 1) { System.out.println("Usage: ShowFile File"); return; } try { // Открытие файла. fin = new FilelnputStream(args[0]); } catch(FileNotFoundException exc) { System.out.println("File Not Found"); return; } try { // читать из файла до тех пор, пока не встретится знак EOF. do { // Чтение из файла. i = fin.read; if(i != -1) System.out.print((char) i) ; // Если значение переменной i равно -1,значит, // достингут конец файла. } while (i != -1); } catch(IOException exc) { System.out.println("Error reading file."); } try { // Закрытие файла. fin.close ; } catch(IOException exc) { System.out.println("Error closing file."); } } }
В приведенном выше примере поток ввода из файла закрывается после того, как чтение данных из файла завершается в блоке try. Такой способ оказывается удобным не всегда, и поэтому в Java предоставляется более совершенный и чаще употребляемый способ. А состоит он в вызове метода close в блоке finally. В этом случае все методы, получающие доступ к файлу, помещаются в блок try, а для закрытия файла используется блок finally. Благодаря этому файл закрывается независимого от того, как завершится блок try. Если продолжить предыдущий пример, то блок try, в котором выполняется чтение из файла, можно переписать следующим образом: try { do { i = fin.read; if(i != -1) System.out.print((char) i) ; } while(i != —1) ; } catch(IOException exc) { System.out.println("Error Reading File"); // Блок finally используется для закрытия файла. } finally { // закрыть файл при выходе из блока try. try { fin.close ; } catch(IOException exc) { System.out.println("Error Closing File"); } }