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 {
    // Создать связь с текстовым файлом: 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();
  }
}

 


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