Класс PrintStream в Java

🔥 🚀 Важно для всех, кто работает с Java! 🔥
На JavaRocks ты найдешь уникальные туториалы, практические задачи и редкие книги, которых не найти в свободном доступе. Присоединяйся к нашему Telegram-каналу JavaRocks — стань частью профессионального сообщества!

Всем привет! Сегодня мы поговорим о классе PrintStream, его методах, а также о переменных System.out и System.in

Наиболее базовыми методами этого класса являются print() и println(). Поскольку переменная System.out является объектом PrintStream, при вызове System.out.println() мы вызываем один из методов этого класса.

Основное назначение класса PrintStream – отправлять информацию в какой-либо поток.

Запись данных в файл с помощью PrintStream

У этого класса PrintStream есть несколько конструкторов. Вот некоторые из тех, которые используются наиболее часто:

  • PrintStream(OutputStream outputStream)
  • PrintStream(File outputFile) throws FileNotFoundException
  • PrintStream(String outputFileName) throws FileNotFoundException

PrintStream умеет создавать поток вывода, работая как с именем файла, так и с готовым объектом File, поэтому мы можем передать или имя выходного файла в конструктор 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);

   }
}
Run Code

Этот код создаст на рабочем столе файл test.txt (если он еще не существует) и последовательно запишет в него наше число, строку и булево значение.

Вот содержимое файла после запуска программы:

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);
   }
}
Run Code

Этот код выполнит те же действия, что и предыдущий.

Метод printf()

Еще один интересный метод, заслуживающий нашего внимания, – 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\\Steve\\Desktop\\test.txt");

       printStream.println("Hello!");
       printStream.println("I'm a robot!");

       printStream.printf("My name is %s. I am %d!", "Amigo", 18);

       printStream.close();
   }
}
Run Code

Приведенный код выводит несколько строк, представляющих робота. Важно: вместо явного указания его имени и возраста в строке мы используем места для заполнения %s и %d. В английском они называются placeholders – места, в которые динамически вставляются значения переменных. Их мы передаем в качестве аргументов: в нашем случае это строка“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. I am %d!";

   public static void main(String[] args) throws IOException {

       PrintStream printStream = new PrintStream("C:\\Users\\Steve\\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();
   }
}
Run Code

Замена System.in

Рассмотрим, как переопределить стандартный поток ввода System.in, чтобы можно было получать данные из любого источника. Нам поможет такая конструкция:

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 = "Hi! My name is Amigo!\nI'm learning Java on the CodeGym website.\nOne day I will become a cool programmer!\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);
       }

   }
}
Run Code

По умолчанию System.in указывает на поток ввода с клавиатуры. Что делать, если мы хотим, чтобы данные считывались из обычной строки?

Создаем строку и получаем ее в виде массива байтов. Причем здесь байты? Дело в том, что InputStream – это абстрактный класс, поэтому мы не можем создать его экземпляр напрямую. Вместо этого необходимо выбрать класс-наследник, например, ByteArrayInputStream. Он довольно простой, и даже название говорит за себя: ByteArrayInputStream использует в качестве источника данных массив байтов.

Итак, мы создаем массив байтов и передаем его в конструктор потока, который будет считывать данные. Остается лишь воспользоваться методом System.setIn(), чтобы явно задать значение переменной in. При работе с System.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);
       }
Run Code

Теперь при запуске вы увидите, что наша строка автоматически выводится в консоль. Чтения с клавиатуры не происходит: мы успешно заменили источник данных!

Может также быть полезно: «Как вывести массив в консоль в Java»

Перевод статьи «Java PrintStream Class».

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх