Java если не закрыть файл

Java если не закрыть файл

При завершении работы с потоком его надо закрыть с помощью метода close() , который определен в интерфейсе Closeable . Метод close имеет следующее определение:

void close() throws IOException

Этот интерфейс уже реализуется в классах InputStream и OutputStream, а через них и во всех классах потоков.

При закрытии потока освобождаются все выделенные для него ресурсы, например, файл. В случае, если поток окажется не закрыт, может происходить утечка памяти.

Есть два способа закрытия файла. Первый традиционный заключается в использовании блока try..catch..finally . Например, считаем данные из файла:

import java.io.*; public class Program < public static void main(String[] args) < FileInputStream fin=null; try < fin = new FileInputStream("C://SomeDir//notes.txt"); int i=-1; while((i=fin.read())!=-1)< System.out.print((char)i); >> catch(IOException ex) < System.out.println(ex.getMessage()); >finally < try< if(fin!=null) fin.close(); >catch(IOException ex) < System.out.println(ex.getMessage()); >> > >

Поскольку при открытии или считывании файла может произойти ошибка ввода-вывода, то код считывания помещается в блок try. И чтобы быть уверенным, что поток в любом случае закроется, даже если при работе с ним возникнет ошибка, вызов метода close() помещается в блок finally . И, так как метод close() также в случае ошибки может генерировать исключение IOException, то его вызов также помещается во вложенный блок try..catch

Начиная с Java 7 можно использовать еще один способ, который автоматически вызывает метод close. Этот способ заключается в использовании конструкции try-with-resources (try-с-ресурсами). Данная конструкция работает с объектами, которые реализуют интерфейс AutoCloseable . Так как все классы потоков реализуют интерфейс Closeable , который в свою очередь наследуется от AutoCloseable , то их также можно использовать в данной конструкции

Читайте также:  Css make div shadow

Итак, перепишем предыдущий пример с использованием конструкции try-with-resources:

import java.io.*; public class Program < public static void main(String[] args) < try(FileInputStream fin=new FileInputStream("C://SomeDir//notes.txt")) < int i=-1; while((i=fin.read())!=-1)< System.out.print((char)i); >> catch(IOException ex) < System.out.println(ex.getMessage()); >> >

Синтаксис конструкции следующий: try(название_класса имя_переменной = конструктор_класса) . Данная конструкция также не исключает использования блоков catch .

После окончания работы в блоке try у ресурса (в данном случае у объекта FileInputStream ) автоматически вызывается метод close().

Если нам надо использовать несколько потоков, которые после выполнения надо закрыть, то мы можем указать объекты потоков через точку с запятой:

try(FileInputStream fin=new FileInputStream("C://SomeDir//Hello.txt"); FileOutputStream fos = new FileOutputStream("C://SomeDir//Hello2.txt")) < //. >

Источник

Автоматическое закрытие файлов в Java

Автоматическое закрытие файлов в Java

Во многих Java программ, для закрытия фай­лов, которые больше не нужны, метод close() вызывается явным образом.

Такой способ закрытия файлов используется еще с тех пор, как вышла первая версия Java. Именно поэтому он часто встречается в существующих программах. Более того, он до сих пор остается вполне оправданным и полезным.

Однако в версию JDK 7 включено новое средство, предоставляющее другой, более рациональный способ управления ресурсами,в том числе и потоками файлового ввода-вывода, автоматизирующий процесс закрытия файлов.

Этот способ основывается на новой разновидности оператора try, называемой оператором try с ресурсами, а иногда еще — автоматическим управлением ресурсами.

Главное преимущество оператора try с ресурсами заключается в том, что он предот­вращает ситуации, в которых файл (или другой ресурс) непреднамеренно остается не­освобожденным и после того, как необходимость в его использовании отпала.

Внимание! Если не позаботиться о своевременном закрытии файлов, то это может привести к утечке памяти и прочим осложнениям в работе программы.

Так выглядит общая форма оператора try с ресурсами:

Здесь описание_ресурса включает в себя объявление и инициализацию ресур­са, такого как файл. По сути, в это описание входит объявление переменной, которая инициализируется ссылкой на объект управляемого ресурса.

По завершении блока try объявленный ресурс автоматически освобождается. Если этим ресурсом является файл, то он автоматически закрывается, что избавляет от необходимости вызывать метод close() явным образом. Оператор try с ресурсами также может включать блоки catch и finally.

Область применимости таких операторов try ограничена ресурсами, которые реа­лизуют интерфейс AutoCloseable, определенный в пакете java.lang.

В этом интер­фейсе определен метод close(). Интерфейс AutoCloseable наследуется интерфейсом Closeable, определенным в пакете java.io. Оба интерфейса реализуются классами потоков, в том числе FileinputStream и FileOutputStream. Следовательно, оператор try с ресурсами может применяться вместе с потоками, включая потоки файлового вво­да-вывода.

В качестве примера ниже приведена версия программы, в которой оператор try с ресурсами используется для автоматического закрытия файла.

Обратите внимание на то, как открывается файл в операторе try с ресурсами:

Здесь сначала объявляется переменная fin типа FileinputStream, а затем этой пе­ременной присваивается ссылка на файл, который выступает в роли объекта, откры­ваемого с помощью конструктора класса FileinputStream.

Таким образом, в данной версии программы переменная fin является локальной по отношению к блоку try и создается при входе в этот блок. При выходе из блока try файл, связанный с перемен­ной fin, автоматически закрывается с помощью неявно вызываемого метода close().

Это означает, что теперь отсутствует риск того, что вы забудете закрыть файл путем яв­ного вызова метода close() . В этом и состоит главное преимущество автоматического управления ресурсами.

Важно понимать, что ресурс, объявленный в операторе try, неявно принимает мо­дификатор final. Это означает, что после создания ресурсной переменной ее значение не может быть изменено. Кроме того, ее область действия ограничивается блоком опе­ратора try.

С помощью одного подобного оператора try можно управлять несколькими ре­сурсами. Для этого достаточно указать список объявлений ресурсов, разделенных точ­кой с запятой.

В качестве примера ниже приведена версия программы CopyFile. В этой версии оба ресурса, fin и fout, управляются одним оператором try.

Обратите внимание на то, как входной и выходной файлы открываются в операторе:

По завершении этого блока try оба файла, на которые ссылаются переменные fin и fout, будут автоматически закрыты.

Если сравнить эту версию программы с предыду­щей, то можно заметить, что ее исходный код намного компактнее. Возможность соз­дания более компактного кода является еще одним, дополнительным преимуществом оператора try с ресурсами.

Стоит упомянуть еще об одной особенности оператора try с ресурсами. Вообще говоря, возникшее при выполнении блока try исключение может породить другое ис­ключение при закрытии ресурса в блоке finally.

В случае «обычного» оператора try первоначальное исключение теряется, будучи прерванным вторым исключением. Но в случае оператора try с ресурсами второе исключение подавляется.

При этом оно не те­ряется, а просто добавляется в список подавленных исключений, связанных с первым исключением. Этот список можно получить, вызвав метод getSuppressed(), определенный в классе Throwable.

Не менее важным остается и умение использовать традиционный способ освобождения ресурсов с помощью явного вызова метода close(). И на то имеется ряд веских причин.

Во-первых, среди уже существующих и повсеместно эксплуатируемых программ на Java немало таких, в которых применяется традиционный способ управле­ния ресурсами. Поэтому вы должны как следует усвоить традиционный подход и уметь использовать его для сопровождения устаревшего кода.

Во-вторых, переход к использо­ванию версии JDK 7 может произойти не сразу, а следовательно, вы будете вынуждены работать с предыдущей версией данного комплекта. В этом случае воспользоваться пре­имуществами оператора try с ресурсами не удастся, и придется применять традицион­ный способ управления ресурсами.

И наконец, в некоторых случаях закрытие ресурса явным образом оказывается более эффективным, чем его автоматическое освобождение.

И все же, если вы работаете с версией JDK 7, JDK 8 или более поздней, вариант автоматического управления ресурсами, как более рациональный и надежный, следует считать предпочтительным.

Советуем следующее видео к просмотру:

Источник

Java. Автоматическое закрытие файла. Оператор try с ресурсами. Примеры

Любой файл, который открывается и используется должен быть закрыт с помощью вызова метода close() . Если этого не сделать, то это может привести к вытоку памяти и связанных с этим осложнений.

В версии JDK 7 появилась новая возможность управления потоками ввода вывода в файлы – автоматическое управление ресурсами (ARM – Automatic Resource Management) или автоматическое завершение процесса. Эта возможность основана на усовершенствованной версии оператора try и состоит в предотвращении случаев ошибочного не закрытия файла (не освобождения ресурса).

Общая форма оператора try , который обеспечивает автоматическое управление ресурсами, следующая:

try (resource_specification) < // использование ресурса // . >

здесь resource_specification – оператор, который объявляет и инициализирует такой ресурс, как поток ввода/вывода в файл. В операторе resource_specification объявляется переменная, которая есть ссылкой на управляемый объект. В случае с файлом, объявляется переменная, которая есть ссылкой на файловый объект.

Вышеприведенный оператор еще называется оператор try с ресурсами.

Возможна другая форма использования оператору try с ресурсами. При такой спецификации оператор try с ресурсами может содержать блоки catch и finally .

try (resource_specification) < // использование ресурса // . > catch (. ) < // обработка ошибок // . > finally < // блок завершения // . >
2. Использование оператора try с ресурсами. Конвертирование содержимого файла в массив строк. Пример

В примере демонстрируется функция GetLinesFromFile() , которая конвертирует содержимое текстового файла в массив строк типа String[] . В функции используется оператор try с ресурсами, в котором в качестве ресурса фигурирует файловый объект с именем fr . В операторе try нету вызова метода fr.close() . Этот метод будет вызван автоматически.

import java.io.*; . // Получить строки файла в виде массива String[] public static String[] GetLinesFromFile(String filename) throws IOException < // Объявить внутренние переменные String lines[] = null; // массив строк - результат String lines2[] = null; // дополнительный массив строк String s; // дополнительная переменная - строка int symbol; // Оператор try с ресурсами. // Создается файловый объект fr, который связан с файлом "textfile.txt" try (FileReader fr = new FileReader(filename)) < // Начальная инициализация перед входом в цикл lines = new String[0]; // создать массив из 0 строк s = ""; // Цикл чтения символов из файла и создание массива lines[] do < // Считать символ из файла symbol = fr.read(); if ((char)symbol == '\n') < // удалить из s символ '\n' s = s.substring(0,s.length()-1); // добавить в массив строк lines[] строку s lines2 = new String[lines.length+1]; // создать новый массив lines2[] for (int i=0; i// Очистить строку s s = ""; >  else < s = s + (char)symbol; > > while (fr.ready()); // здесь файл не нужно закрывать, // метод fr.close() будет вызван автоматически >  catch (FileNotFoundException e) < System.out.println("File not found.");  return null; > catch (IOException e) < System.out.println("I/O error.");  return null; > return lines; >

Использование метода GetLinesFromFile() может быть, например, таким

public static void main(String[] args) throws IOException < String lines[]; lines = GetLinesFromFile("textfile.txt"); if (lines!=null) < // Вывести масив lines[] для контроля System.out.println("The content of file \"textfile.txt\""); for (int i=0; iout.println(lines[i]); > >
3. Оператор try с ресурсами, который содержит несколько файловых объектов. Пример

В операторе try может быть создано одновременно несколько файловых объектов (ресурсов). В нижеследующем примере объявляется функция CopyTextFiles() , в которой реализовано копирование текстовых файлов.

В функции реализован оператор try с ресурсами, который управляет двумя ресурсами одновременно. Первый ресурс fr это файловый объект, который есть источником (файл-оригинал). Второй ресурс fw – это файловый объект, который есть приемником или копией.

import java.io.*; public static void CopyTextFiles(String filename1, String filename2) throws IOException < try (FileReader fr = new FileReader(filename1); FileWriter fw = new FileWriter(filename2)) < int symbol; do < symbol = fr.read(); fw.write(symbol); >while (fr.ready()); // Не нужно вызывать методы fr.close() и fw.close(), // эти методы будут вызваны автоматически > catch (IOException e) < System.out.println("Error: " + e.getMessage());  return; > >

Вызов функции из другого кода может быть, например, таким

public static void main(String[] args) throws IOException < CopyTextFiles("textfile.txt", "textfile3.txt"); >

Связанные темы

Источник

Оцените статью