Вітання! Сьогодні поговоримо про клас
PrintStream
та все, що він вміє робити. Власне, з двома методами класу PrintStream
ти вже знайомий. Це методи print()
і println()
, якими ти користуєшся, напевно, щодня :) Оскільки змінна System.out
є об'єктом PrintStream
, викликаючи метод System.out.println()
, ти викликаєш метод саме цього класу. Загальне призначення класу PrintStream
- виведення інформації в якийсь потік. Цей клас має кілька конструкторів. Ось кілька найпоширеніших:
PrintStream(OutputStream outputStream)
PrintStream(File outputFile) throws FileNotFoundException
PrintStream(String outputFileName) throws FileNotFoundException
PrintStream
, наприклад, назву файлу, який необхідно вивести дані. Або ж, як альтернативу, сам об'єкт File
. Давай розглянемо, як це працює на прикладах:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Main {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
filePrintStream.println(222);
filePrintStream.println("Hello world");
filePrintStream.println(false);
}
}
Цей код створить на робочому столі файл test.txt
(якщо він там ще не існує) і запише туди послідовно наші число, рядок і boolean
змінну. Ось вміст нашого файлу після роботи програми:
222
Hello world!
false
Як ми сказали вище, не обов'язково передавати сам об'єкт файлу File
. Досить просто вказати у конструкторі шлях до нього:
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Main {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream("C:\\Users\\Username\\Desktop\\test.txt");
filePrintStream.println(222);
filePrintStream.println("Hello world");
filePrintStream.println(false);
}
}
Цей код зробить те саме, що й попередній. Ще один цікавий метод, на який варто звернути увагу, — printf()
виведення форматованого рядка. Що означає «форматований рядок»? Щоб пояснити, наведу приклад:
import java.io.IOException;
import java.io.PrintStream;
public class Main {
public static void main(String[] args) throws IOException {
PrintStream printStream = new PrintStream("C:\\Users\\Евгений\\Desktop\\test.txt");
printStream.println("Hello!");
printStream.println("I'm robot!");
printStream.printf("My name is %s, my age is %d!", "Amigo", 18);
printStream.close();
}
}
Тут замість того, щоб явно записувати в рядку ім'я та вік нашого робота, ми ніби залишаємо для цієї інформації «вільне місце» за допомогою покажчиків %s
та %d
. А ті дані, які мають опинитися в цих місцях, ми передаємо як параметри. У нашому випадку це рядок Amigo і число 18. Ми могли б, наприклад, створити ще один простір: скажімо, %b
, і передати ще один параметр. Для чого це потрібно? Насамперед, підвищення гнучкості. Якщо у твоїй програмі необхідно буде часто виводити вітальне повідомлення, то для кожного нового робота тобі доведеться вручну набирати потрібний текст. Ти не зможеш навіть винести цей текст у константу: імена і вік у всіх різні! Але використовуючи новий метод, ти можеш вивести рядок з вітанням до константи, а при необхідності просто змінювати параметри у методі printf()
.
import java.io.IOException;
import java.io.PrintStream;
public class Main {
private static final String GREETINGS_MESSAGE = "My name is %s, my age is %d!";
public static void main(String[] args) throws IOException {
PrintStream printStream = new PrintStream("C:\\Users\\Евгений\\Desktop\\test.txt");
printStream.println("Hello!");
printStream.println("We are robots!");
printStream.printf(GREETINGS_MESSAGE, "Amigo", 18);
printStream.printf(GREETINGS_MESSAGE, "R2-D2", 35);
printStream.printf(GREETINGS_MESSAGE, "C-3PO", 35);
printStream.close();
}
}
Підміна System.in
У цій лекції ми «боротимемося з системою» і навчимося підмінювати зміннуSystem.in
і перенаправлятимемо системний висновок у потрібне нам місце. Ти міг призабути що таке System.in
, але цю конструкцію жоден студент JavaRush не забуде ніколи:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.in
(як і System.out
) - це статична змінна класу System
. Але, на відміну System.out
, вона належить до іншого класу, саме — до InputStream
. За промовчанням System.in
– це потік, що зчитує дані із системного пристрою – клавіатури. Однак, як і у випадку з System.out
, ми можемо підмінити джерело даних, і читання відбуватиметься не з клавіатури, а з потрібного місця! Давай розглянемо приклад:
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
String greetings = "Вітання! Меня зовут Амиго!\nЯ изучаю Java на сайте JavaRush.\nОднажды я стану крутым программистом!\n";
byte[] bytes = greetings.getBytes();
InputStream inputStream = new ByteArrayInputStream(bytes);
System.setIn(inputStream);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str;
while ((str = reader.readLine())!= null) {
System.out.println(str);
}
}
}
Отже, що ми зробабо? Зазвичай System.in
прив'язана до клавіатури. Але ми не хочемо, щоб дані читалися з клавіатури: нехай читаються зі звичайного рядка з текстом! Ми створабо рядок і отримали його у вигляді масиву байт. Навіщо нам байти? Справа в тому, що InputStream
абстрактний клас, і ми не можемо створити його екземпляр. Доведеться вибрати якийсь клас із його спадкоємців. Для прикладу можемо взяти ByteArrayInputStream
. Він простий, і з назві зрозуміло, як і працює: джерелом даних йому є масив байт. Так що ми створюємо цей наймасивніший байт і передаємо в конструктор нашому stream
'у, який читатиме дані. Власне, все вже готове! Тепер нам достатньо використати метод System.setIn()
, щоб явно встановити значення змінної in
. У випадку зout
, Як пам'ятаєш, встановити значення змінної явно теж не можна: доводилося використовувати спеціальний метод setOut()
. Після того, як ми привласнабо створений нами InputStream
змінною System.in
, треба перевірити, чи спрацював наш задум. У цьому нам допоможе старий знайомий BufferedReader
. У звичайній ситуації цей код привів би до того, що в тебе в Intellij IDEa відкрилася б консоль, і звідти зчитувалися дані, які ти вводив із клавіатури.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str;
while ((str = reader.readLine())!= null) {
System.out.println(str);
}
Але запустивши його тепер ти побачиш, що в консоль просто виведеться наш текст із програми, жодного зчитування з клавіатури не буде. Ми підмінабо джерело даних, тепер ним є не клавіатура, а наш рядок! Ось так легко і просто :) У сьогоднішній лекції ми познайомабося з новим класом і розглянули новий невеликий хак по роботі з введенням-висновком. Саме час повернутися до курсу та вирішити кілька завдань:) Побачимося на наступній лекції!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ