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

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


Зміст


Пошук на інших ресурсах:




1. Автоматичне закриття файлу з допомогою блоку try. Оператор 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<lines.length; i++)
          lines2[i] = lines[i];
        lines2[lines.length] = s;                            
        lines = lines2;

        // Очистити рядок 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; i<lines.length; i++)
      System.out.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");      
}

  


Зв’язані теми