Java. Приклади реалізації операцій, які модифікують текстові файли. Класи FileReader, FileOutputStream, PrintStream

Приклади реалізації операцій, які модифікують текстові файли. Класи FileReader, FileOutputStream, PrintStream


Зміст


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




1. Функція CountLinesInFile(). Обчислити кількість рядків у символьному файлі

Для обчислення кількості рядків у символьному файлі можна застосувати наступну функцію

import java.io.*;

...

// Обчислити кількість рядків у файлі
public static int CountLinesInFile(String filename) throws IOException {
  // 1. Оголосити внутрішні змінні
  int count = 0; // к-сть рядків у файлі - результат
  FileReader fr = null;
  int symbol;

  try {
    // 2. Спроба відкрити файл для читання
    fr = new FileReader(filename); 

    // Цикл читання символів з файлу та підрахунку їх кількості
    do {
      // Зчитати символ з файлу
      symbol = fr.read(); 

      // Перевірити, чи символ кінця рядка
      if ((char)symbol == '\n') 
        count++; // Збільшити кількість рядків у файлі на 1
    } while (fr.ready()); // Перевірка, чи не кінець файлу 
  }
  catch (IOException e)
  {
    // 3. Якщо файл не відкрито, то вивести відповідне повідомлення
    System.out.println("I/O error: " + e);
  }
  finally {
    // 4. Закрити файл, якщо він був відкритий 
    try {
      if (fr!=null) {
        fr.close();
      }
    }
    catch (IOException e) {
      System.out.println("File close error.");
    } 
  }

  // 5. Повернути результат
  return count; 
}

Використання функції в іншому програмному коді може бути, наприклад, таким

...

public static void main(String[] args) throws IOException {
  // Викликати функцію CountLinesInFile() для файлу "textFile.txt"
  int count = CountLinesInFile("textFile.txt");
  System.out.println("count = " + count);
}

...

 

2. Функція GetLinesFromFile(). Отримати рядки файлу у вигляді масиву рядків типу String[]

Нижче наведено функцію GetLinesFromFile(), яка повертає масив рядків файлу типу String[]. Якщо у файлі немає рядків або виникає помилка, то функція повертає null. У своїй роботі дана функція використовує функцію CountLinesInFile() (дивіться п.1) для визначення кількості рядків у файлі.
Для отримання масиву рядків у функції використовуються засоби класу FileReader. Функція використовується у наступних прикладах даної теми.

import java.io.*;

...

// Отримати рядки файлу у вигляді масиву String[]
public static String[] GetLinesFromFile(String filename) throws IOException {
  // 1. Оголосити внутрішні змінні
  int count; // к-сть рядків у файлі
  String lines[] = null; // масив рядків - результат
  FileReader fr = null;
  String s; // додаткова змінна - рядок
  int symbol;
  int i;

  // 2. Отримати к-сть рядків у файлі - викликати функцію CountLinesInFile() 
  count = CountLinesInFile(filename);

  // 3. Перевірка, чи у файлі є рядки
  if (count<=0) return null;

  // 4. Виділити пам'ять для count рядків
  lines = new String[count];

  // 5. Читання даних з файлу та утворення масиву lines[]
  try {
    // 5.1. Спроба відкрити файл для читання
    fr = new FileReader(filename); 

    // 5.2. Цикл читання символів з файлу та утворення масиву lines
    s = ""; 
    i = 0;
    do {
      // Зчитати символ з файлу
      symbol = fr.read();

      // Перевірити, чи символ кінця рядка
      if (((char)symbol == '\n')) { 
        // видалити з s символ '\n'
        s = s.substring(0, s.length()-1);

        // Додати до масиву рядків рядок s 
        lines[i] = s;
        s = "";
        i++; // Збільшити кількість рядків у файлі на 1
      }
      else {
        // додати символ до рядка
        s = s + (char)symbol;
      }
    } while (fr.ready()); // Перевірка, чи не кінець файлу 
  }
  catch (IOException e)
  {
    // 5.3. Якщо файл не відкрито, то вивести відповідне повідомлення
    System.out.println("I/O error: " + e);
  }
  finally {
    // 5.4. Закрити файл, якщо він був відкритий 
    try {
      if (fr!=null) {
        fr.close();
      }
    }
    catch (IOException e) {
      System.out.println("File close error.");
    } 
  }

  // 6. Повернути результат
  return lines;
}

Нижче наведено приклад можливого використання функції:

... 

public static void main(String[] args) throws IOException {
  // Отримати рядки файлу у вигляді масиву (списку)
  String lns[]; 
  lns = GetLinesFromFile("textFile.txt");
  System.out.println("\n\nThe content of file is:");
  for (int i=0; i<lns.length; i++)
    System.out.println(lns[i]);
}

...

 

3. Функція WriteLinesToFile(). Записати масив типу String[] у файл

При роботі з файлами корисною може бути функція запису масиву рядків типу String[] у файл. Функція використовує можливості класів FileOutputStream та PrintStream.

import java.io.*;

...

// Записати масив типу String[] у файл
public static void WriteLinesToFile(String lines[], String filename) throws IOException {

  // 1. Оголосити внутрішні змінні
  FileOutputStream fs = null;
  PrintStream ps = null;

  try {
    // 2. Створити екземпляри класів FileOutputStream, PrintStream
    fs = new FileOutputStream(filename); // створити файловий потік
    ps = new PrintStream(fs); // зв'язати файловий потік з потоком виведення PrintStream

    // 3. Цикл запису масиву lines[] у файл
    for (int i=0; i<lines.length; i++)
      ps.println(lines[i]); 
  }
  catch (IOException e) {
    // Якщо помилка відкриття файлу або інша помилка
    System.out.println("I/O error: " + e);
  }
  finally {
    if (fs!=null) {
      try {
        fs.close();
      }
      catch (IOException e2) {
        System.out.println("Error closing " + filename);
      } 
    } 

    if (ps!=null) {
      ps.close();
    }
  } 
}

 

4. Функція ReplaceStringInFile(). Замінити заданий рядок у текстовому файлі

Щоб замінити заданий рядок у файлі потрібно вказати його позицію. Заміна рядка здійснюється за наступним алгоритмом:

  • отримати рядки файлу у вигляді масиву String[];
  • замінити рядок в масиві;
  • записати масив знову в файл.

За подібним алгоритмом можна реалізувати будь-які інші операції з файлами. Для читання рядків з файлу та їх запис в файл можна використати функції з пунктів 2, 3 даної теми.

Текст функції ReplaceStringInFile() наступний.

import java.io.*;

...

// Замінити рядок у файлі в заданій позиції.
// Параметри функції:
// - position - позиція рядка у файлі;
// - str - рядок, який повинен бути замінений;
// - filename - ім'я файлу, в якому замінюється рядок.
// Якщо операція відбулась успішно, то функція повертає true.
public static boolean ReplaceStringInFile(int position, String str, String filename)
    throws IOException {

  // 1. Виконати необхідні перевірки
  // Чи значення position коректне?
  int count = CountLinesInFile(filename); // к-сть рядків у файлі 
  if ((position<0) || (position>=count)) return false;

  // 2. Отримати список рядків файлу
  String lines[] = GetLinesFromFile(filename);

  // 3. Замінити рядок в позиції position
  lines[position] = str;

  // 4. Записати змінений список рядків знову в файл
  WriteLinesToFile(lines, filename); 

  return true;
}

Використання функції може бути, наприклад, таким

...

public static void main(String[] args) throws IOException {
  // Використання функції ReplaceStringInFile()
  boolean res;
  res = ReplaceStringInFile(7, "0000", "textFile.txt");

  if (res)
    System.out.println("Ok");
  else
    System.out.println("Fail");
}

...

 

5. Функція SortLinesInFile(). Сортування рядків у файлі методом вставки

Сортування рядків відбувається за тим самим принципом, що і в пункті 4. Спочатку рядки файлу копіюються в тимчасовий масив типу String[]. Потім відбувається сортування тимчасового масиву. На останньому кроці посортований масив копіюється знову в файл.

У своїй роботі функція SortLinesInFile() використовує дві функції GetLinesFromFile() та WriteLinesToFile(), реалізація яких описується в пунктах 2, 3.

Текст функції наступний.

import java.io.*;

...

// Сортування рядків у файлі.
// Параметри:
// - filename - ім'я файлу;
// - order - порядок сортування,
// якщо order=true то посортувати в порядку зростання.
public static boolean SortLinesInFile(String filename, boolean order)
    throws IOException {

  String s;

  // 1. Отримати рядки файлу у вигляді масиву String[]
  String lines[] = GetLinesFromFile(filename);

  // 2. Якщо у файлі є рядки, то посортувати їх
  if (lines!=null) {
    // цикл сортування методом вставки
    for (int i=0; i<lines.length-1; i++)
      for (int j=i; j>=0; j--)
        if (order) {
          if (lines[j].compareTo(lines[j+1])>0) {
            s = lines[j];
            lines[j] = lines[j+1];
            lines[j+1] = s;
          }
        }
        else {
          if (lines[j].compareTo(lines[j+1])<0) {
            s = lines[j];
            lines[j] = lines[j+1];
            lines[j+1] = s;
          }
        }

    // 3. Записати посортовані рядки у файл
    WriteLinesToFile(lines, filename);

    // 4. Повернути результат
    return true;
  }

  return false;
}

Використання функції може бути, наприклад таким

public static void main(String[] args) throws IOException {
  // Використання функції ReplaceStringInFile()
  boolean res;
  res = SortLinesInFile("textFile.txt", false);

  if (res)
    System.out.println("Ok");
  else
    System.out.println("Fail.");
}

 

6. Запис/читання масиву цілих чисел у текстовий файл. Приклад

У прикладі наведено програмний код, який виконує наступну роботу:

  • записує у файл масив цілих чисел;
  • читає масив цілих чисел з файлу.

Для виконання задачі розроблено клас ReadWriteArrayFile, в якому реалізовані два методи:

  • saveToFileTxt() – призначений для запису масиву у файл. Посилання на масив та ім’я файлу є вхідними параметрами методу;
  • readFromFileTxt() – читання з файлу масиву цілих чисел у наперед визначеному форматі. Ім’я файлу передається в метод вхідним параметром.

За даним прикладом можна розробляти власні методи, які виконують:

  • запис (збереження) різнотипних даних у файл у заданому форматі;
  • читання різнотипних даних з файлу в заданому форматі.

 

import java.util.*;
import java.io.*;

class ReadWriteArrayFile {
  // Записати масив цілих чисел у текстовий файл у форматі:
  // - N - кількість чисел;
  // - число1;
  // - число2;
  // - ...
  // - числоN.
  // Параметри методу:
  // - A - масив чисел;
  // - filename - ім'я файлу
  void saveToFileTxt(int[] AI, String filename) throws IOException {
    // Створити зв'язок з текстовим файлом filename: fOut -> filename
    FileOutputStream fOut = new FileOutputStream(filename);

    // Створити зв'язок з екземпляром fOut: ps -> fOut -> filename
    PrintStream pS = new PrintStream(fOut);

    // Записати масив AI
    pS.println(AI.length);
    for (int i=0; i<AI.length; i++) {
      pS.println(AI[i]);
    }
    pS.close();
    fOut.close();
  }

  // Зчитати масив чисел з текстового файлу.
  // Формат файлу:
  // - N - кількість чисел;
  // - число1;
  // - число2;
  // - ...
  // - числоN.
  int[] readFromFileTxt(String filename) throws IOException {
    // 1. Зв'язати файл filename з екземпляром fInput: fInput <- filename
    FileInputStream fInput = new FileInputStream(filename);

    // 2. Зв'язати екземпляр класу Scanner з екземпляром fInput:
    //    scanner <- fInput <- filename
    Scanner scanner = new Scanner(fInput);

    // 3. Оголосити додаткові змінні
    int[] AI = null; // Результуючий масив
    int count; // Кількість чисел у масиві

    // 4. Зчитати кількість чисел у масиві
    count = scanner.nextInt();

    // 5. Виділити пам'ять для масиву AI
    AI = new int[count];

    // 6. Прочитати числа
    for (int i=0; i<AI.length; i++)
      AI[i] = scanner.nextInt();

    // 7. Закрити потоки
    scanner.close();
    fInput.close();

    // 8. Повернути масив
    return AI;
  }
}

public class Threads {

  public static void main(String[] args) throws IOException {
    // Запис/читання масиву цілих чисел у файл
    // 1. Створити екземпляр класу ReadWriteArrayFile
    ReadWriteArrayFile obj = new ReadWriteArrayFile();

    // 2. Створити тестувальний масив
    int[] AI = { 2, 5, -1, 8, 4, 9 };

    // 2. Записати у файл "myFile1.txt" масив
    obj.saveToFileTxt(AI, "myFile1.txt");

    // 3. Зчитати з файлу "myFile1.txt" масив в екземпляр AI2
    int[] AI2 = obj.readFromFileTxt("myFile1.txt");

    // 4. Вивести прочитаний масив для контролю
    System.out.println();
    for (int i=0; i<AI2.length; i++)
      System.out.print(AI2[i] + " ");
    System.out.println();
  }
}

 


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