Java. Робота з консоллю в Java. Класи InputStreamReader, PrintStream

Робота з консоллю в Java. Класи InputStreamReader, PrintStream. Створення потоку вводу/виводу зв’язаного з консоллю. Перенаправлення потоків вводу/виводу у файл, з файлу, з рядка. Приклади


Зміст


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




1. Створення потоку вводу, зв’язаного з консоллю. Клас InputStreamReader

Потік вводу даних з консолі можна організувати одним з двох способів:

  • з допомогою потоку вводу байтів;
  • з допомогою потоку вводу символів. У цьому випадку дані, що вводяться з консолі, зчитуються з стандартного потоку вводу, якому відповідає змінна System.in з пакету java.lang. Іншими словами, змінна System.in посилається на стандартний потік вводу, яким, за замовчуванням, вважається клавіатура.

У мові Java для реалізації операцій вводу з консолі використовується клас InputStreamReader. Цей клас є підкласом абстрактного базового класу Reader і призначений для конвертування байт в символи.

Щоб отримати об’єкт типу InputStreamReader потрібно створити екземляр цього типу за наступною загальною формою

InputStreamReader objStream = new InputStreamReader(input_stream);

тут

  • objStream – екземпляр, що зв’язаний з потоком вводу символів;
  • inputStream – потік вводу символів. У випадку консолі, цим потоком виступає System.in.

Отже, для потоку System.in, щоб створити екземпляр (об’єкт) типу InputStreamReader, потрібно викликати наступний конструктор

InputStreamReader objStream = new InputStreamReader(System.in);

 

2. Створення потоку виводу, зв’язаного з консоллю. Клас PrintStream. Методи print(), println(). Приклад

В пакеті java.lang реалізовано дві змінні, що зв’язані з потоком запису даних на консоль:

  • System.out. Ця змінна відповідає потоку виведення на консоль;
  • System.err. Ця змінна зв’язана з потоком виведення помилок.

Для роботи з виведенням на консоль розроблено спеціальний клас PrintStream, який є похідним від класу OutputStream. У цьому класі основними є методи print() та println().

Щоб створити потік виводу, зв’язаний з консоллю потрібно оголосити екземпляр класу PrintStream. При створенні екземпляру потрібно зв’язати його з відповідним потоком як показано в наступному прикладі

...

public static void main(String[] args) throws IOException
{
  // Створення потоку виводу. Клас PrintStream.
  // 1. Зв'язати посилання outStream з потоком виводу System.out
  PrintStream outStream = new PrintStream(System.out);

  // 2. Зв'язати посилання errStream з потоком виводу System.err
  PrintStream errStream = new PrintStream(System.err);

  // 3. Використати обидва посилання
  outStream.println("Hello world!"); // Метод println()
  errStream.print("Some error..."); // Метод print()
}

...

Результат виконання програми

Hello world!
Some error...

 

3. Клас InpusStreamReader. Читання символів з консолі з допомогою методу read(). Приклади

Як відомо, з консоллю зв’язана стандартна змінна System.in. Щоб прочитати символи з консолі без буферизації можна використати можливості класу InputStreamReader. Клас InputStreamReader є підкласом абстрактного класу Reader. Клас InputStreamReader призначений для конвертування байт у символи.

Основним методом класу InputStreamReader є метод read(), який має дві перевантажені реалізації. Перша реалізація має наступну загальну форму

int read();

У цьому випадку метод повертає код введеного символу з консолі.

Загальна форма другої реалізації методу наступна

int read(char[] ac, int index, int count);

Тут метод заповнює масив ac типу char[] введеними значеннями символів з консолі. Параметр count задає кількість символів, які потрібно вставити у масив ac. Для масиву ac попередьно має бути виділена пам’ять. Другий варіант методу повертає кількість символів, що можуть бути прочитані.

Приклад 1. Щоб прочитати окремий символ з потоку вводу (консолі) використовується метод read(). Нижче наведено функцію ReadConsolle(), яка демонструє читання символів з консолі без буферизації. Символи читаються до тих пір, поки не буде введено символ ‘ . ‘.

import java.io.*;

...

// Приклад читання символів з консолі System.in
// без використання буферизації.
public void ReadConsolle() throws IOException
{
  char c;

  // Створити екземпляр потоку, що зв'язаний з консоллю
  InputStreamReader sr = new InputStreamReader(System.in);

  System.out.println("Введіть символи, '.' - для виходу.");

  // цикл читання символів
  do {
    c = (char)sr.read();
    System.out.println(c);
  } while (c != '.');
}

Приклад 2. Використання методу read(), який обробляє масив типу char[].

import java.io.*;

...

// Використання варіанту методу read(), що заповнює масив
// символів типу char[] символами, введеними з консолі.
// Загальна форма методу:
// int read(char[], int, int)
public void ReadConsolle2() throws IOException
{
  // 1. Оголосити внутрішні змінні
  char arrChar[] = new char[10];   // масив типу char[] - буфер пам'яті
  InputStreamReader sr = new InputStreamReader(System.in); // потік вводу, що асоціюється з консоллю
  int count; // Кількість прочитаних символів

  // Прочитати 4 символи з консолі.
  // Записати ці символи в масив arrChar починаючи з позиції 0.
  System.out.println("Enter characters (maximum 10):");
  count = sr.read(arrChar, 0, 4);

  // Вивести результат
  System.out.println("You can process " + count + " characters");

  System.out.println("The arrChar after input:");

  for (int i=0; i<arrChar.length; i++)
    System.out.println("arrC[" + i + "] = " + arrChar[i]);
}

Результат виконання програми

Enter characters (maximum 10):
sds
You can process 4 characters
The arrChar after input:
arrC[0] = s
arrC[1] = d
arrC[2] = s
arrC[3] =
arrC[4] =

 

4. Читання символів з консолі з буферизацією. Класи InputStreamReader, BufferedStreamReader. Приклад

Щоб реалізувати буферизацію при читанні символів з консолі, потрібно екземпляр класу InputStreamReader помістити в оболонку об’єкту класу BufferedReader. У цьому випадку, загальна форма конструктора класу BufferedReader наступна

BufferedReader(Reader потік_читання_введених_даних)

тут

  • потік_читання_введених_даних – деякий потік даних (файл, консоль тощо). У випадку консолі тут задається екземпляр класу InputStreamReader (дивіться попередній пункт).

Такий підхід реалізує паттерн Декоратор (Decorator). У паттерні Декоратор екземпляр одного класу служить оболонкою для екземпляру іншого класу. Таким чином відбувається нашаровування об’єктів.

Нижче наведено приклад функції ReadConsoleBuf(), яка реалізує читання символів з консолі з буферизацією.

import java.io.*;

...

// Читання символів з консолі з підтримкою буферизації
public void ReadConsolleBuf() throws IOException {
  char c;

  // Створити екземпляр потоку, що зв'язаний з консоллю
  InputStreamReader sr = new InputStreamReader(System.in);

  // Оголосити екземпляр класу BufferedReader, помістити в нього
  // екземпляр потоку InputStreamReader
  BufferedReader br = new BufferedReader(sr);

  System.out.println("Введіть символи, '.' - для виходу.");

  // цикл читання символів
  do {
    c = (char)br.read();
    System.out.println(c);
  } while (c != '.');
}

 

5. Запис даних, що виводяться на консоль. Вивід масиву дійсних чисел в консоль. Клас PrintStream. Приклад

Приклад є демонстраційним. Виведення відбувається в екземпляр класу PrintStream, який зв’язаний з консоллю (змінною System.out).

public static void main(String[] args) throws IOException
{
  // Вивід масиву дійсних чисел в консоль
  // 1. Створити вхідні дані - масив дійсних чисел. Заповнити масив значеннями
  double AD[] = new double[5];
  for (int i=0; i<AD.length; i++)
    AD[i] = i*2.5 + 1;

  // 2. Створити екземпляр класу PrintStream
  PrintStream ps = new PrintStream(System.out);

  // 3. Вивести масив через метод println()
  ps.println("Array AD:");
  for (int i=0; i<AD.length; i++)
    ps.println(AD[i]);
}

...

 

6. Читання рядків з консолі з підтримкою буферизації та виведення їх на екран. Класи InputStreamReader, BufferedStreamReader. Метод readLine(). Приклад

Читати рядки з консолі можна використовуючи буферизацію або без неї. Якщо використовується механізм буферизації, то клас InputStreamReader поміщається в конструктор класу BufferedReader.

Читання одного рядка здійснюється з допомогою функції readLine().

import java.io.*;

...

public static void main(String[] args) throws IOException
{
  // Зчитати рядки з консолі підтримкою буферизації. Вивести рядки на екран
  // Використати метод readLine()
  InputStreamReader sr = new InputStreamReader(System.in); // створити екземпляр InputStreamReader
  BufferedReader br = new BufferedReader(sr); // екземпляр класу буферизації
  String s;

  System.out.println("Enter strings:");

  do {
    s = br.readLine(); // зчитати один рядок
    System.out.println(s); // вивести цей рядок на екран
  } while (!s.equals("end")); // поки не буде введено рядок "end"
}

...

Результат виконання програми:

Enter strings:
abc
abc
def
def
0 1 2
0 1 2
end
end

 

7. Читання рядків з консолі та запис їх у файл. Класи InputStreamReader, BufferedReader, FileInputStream, PrintStream. Приклад

У прикладі продемонстровано перенаправлення вводу з консолі в текстовий файл.

import java.io.*;

...

public static void main(String[] args) throws IOException
{
  // Зчитати рядки з консолі та записати їх у файл.
  // Використати метод readLine()
  // 1. Оголошення екземплярів класів, що отримують дані (рядки)
  InputStreamReader sr = new InputStreamReader(System.in); // створити екземпляр InputStreamReader
  BufferedReader br = new BufferedReader(sr); // клас буферизації

  // 2. Оголошення екземплярів класів, що виводять рядки
  FileOutputStream fos = new FileOutputStream("strings.txt");
  PrintStream ps = new PrintStream(fos);

  // 3. Додаткова змінна
  String s;

  // 4. Цикл вводу рядків з консолі та запис їх у файл
  System.out.println("Enter strings:");

  do {
    s = br.readLine(); // зчитати один рядок
    System.out.println(s); // вивести цей рядок на екран
    ps.println(s); // записати цей рядок у потік ps => записати у файл "strings.txt"
  } while (!s.equals("end")); // поки не буде введено рядок "end"

  ps.close();
}

Результат виконання програми:

Enter strings:
abc
abc
def
def
0 1 2 3
0 1 2 3
end
end

Вміст файлу “strings.txt”

abc
def
0 1 2 3
end

 

8. Читання рядків з символьного файлу та виведення їх на консоль. Клас FileReader. Приклад

Нехай задано символьний (текстовий) файл, який потрібно вивести на консоль. Читання рядків з файлу можна реалізувати з допомогою методу read() класу FileReader. Рядок з файлу читається у наперед визначену ділянку пам’яті – буфер.

Щоб визначити кінець файлу потрібно використати метод ready() класу FileReader. Якщо кінець файлу, то метод повертає false.

import java.io.*;

...

public static void main(String[] args) throws IOException
{
  // Зчитати рядки з файлу та вивести їх на консоль
  FileReader fr = new FileReader("strings.txt");
  char buffer[] = new char[1000]; // буфер для читання рядків

  // Цикл читання рядків з файлу
  do {
    fr.read(buffer); // Зчитати рядок в буфер buffer
    System.out.println(buffer); // Вивести рядок на консоль
  } while (fr.ready()); // перевірка, чи не кінець файлу

 fr.close();
}

...

 

9. Класи PrintStream, FileOutputStream. Перенаправлення потоку виводу з рядка String у файл. Приклад

Нехай задано деякий рядок типу String. Потрібно записати цей рядок у файл шляхом використання перенаправлення потоку виводу у файл.

Щоб реалізувати запис рядка у файл потрібно виконати наступні дії:

  • створити екземпляр класу FileOutputStream з іменем файлу, в який буде здійснюватись запис рядка;
  • створити екземпляр класу PrintStream, в конструктор якого помістити створений екземпляр класу FileOutputStream;
  • використати один з методів print() або println() для запису рядка у файл.

Фрагмент програмного коду, що здійснює перенаправлення потоку з рядка в файл, наведено нижче

import java.io.*;

...

public static void main(String[] args) throws IOException
{
  // Направити вивід з рядка String у файл з іменем "output.txt"
  // 1. Вхідні дані
  String s = "www.bestprog.net"; // рядок, що записується у файл
  String filename = "output.txt"; // ім'я файлу, в який записується рядок

  // 2. Створити екземпляр класу FileOutputStream
  FileOutputStream fs = new FileOutputStream(filename);

  // 3. Створити екземпляр класу PrintStream, в який помістити екземпляр FileOutputStream
  PrintStream ps = new PrintStream(fs);

  // 4. Записати рядок "www.bestprog.net" у файл "output.txt"
  ps.println(s);

  // 5. Закрити файл
  ps.close();
}

...

За даним прикладом можна реалізувати функцію, яка записує масив рядків у файл.

 


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