Hi! Today we'll talk about the Java PrintStream class and everything it can do. Actually, you are already familiar with two methods of the PrintStream class. They are print() and println(), which you probably use every day :)
Because the System.out variable is a PrintStream object, you are calling one of this class's methods when you call System.out.println().
The general purpose of the PrintStream class is to send information to some stream.
This class has several constructors. Here are some of the most commonly used:
And now everything is ready! Now we just need to use the System.setIn() method to explicitly set the value of the in variable. With out, you will recall, it was also not possible to set the variable's value directly: we had to use the setOut() method.
After we assign our InputStream to the System.in variable, we want to check whether we have achieved our purpose.
Our old friend BufferedReader comes to our aid here.
Normally, this code would have opened the console in IntelliJ IDEA and then read data you entered from the keyboard.

- PrintStream(OutputStream outputStream)
- PrintStream(File outputFile) throws FileNotFoundException
- PrintStream(String outputFileName) throws FileNotFoundException
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);
}
}
This code will create a test.txt file on the desktop (if it doesn't already exist) and sequentially write our number, string, and boolean to it.
Here are the file contents after we run the program:
222
Hello world!
false
As we said above, you don't have to pass a File object. It's enough to simply pass the file path to the constructor:
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);
}
}
This code does the same as the previous code.
Another interesting method worth our attention is printf(), which produces output based on a format string. What is a "format string"?
Let me give an example:
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();
}
}
Here, instead of explicitly stating our robot's name and age in the string, we put placeholders for this information, represented by %s and %d.
And we pass as arguments the data that will replace them. In our case, this is the string "Amigo" and the number 18. We could create another placeholder, say %b, and pass another argument.
Why do we need this? Above all, for greater flexibility.
If your program requires you to display a welcome message often, you would have to manually type out the necessary text for each new robot. You can't even make this text a constant, since everyone has different names and ages!
But using this new method, you can isolate the greeting in a constant and, if necessary, simply change the arguments passed to the printf() method.
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();
}
}
Replacing System.in
In this lesson, we will "fight the system" and learn how to replace the System.in variable in order to redirect system output to wherever we want. You might forget what System.in is, but no CodeGym student will ever forget this construct:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.in (just like System.out) is a static variable of the System class. But unlike System.out, it references another class, namely InputStream.
By default, System.in is a stream that reads data from a system device — the keyboard. However, just as with System.out, we can replace the keyboard as the data source. We can read data from wherever we want!
Let's look at an example:
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);
}
}
}
So what did we do?
System.in is usually bound to the keyboard. But we don't want to read data from the keyboard: let's have the data be read from an ordinary string!
We created a string and got it as a byte array. Why do we need bytes? The thing is that InputStream is an abstract class, so we can't create an instance of it directly. We have to choose one of its descendants. For example, we can choose ByteArrayInputStream. It is simple, and its name alone tells us how it works: its data source is a byte array.
So we create a byte array and pass it to the constructor of our stream that will read the data.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str;
while ((str = reader.readLine())!= null) {
System.out.println(str);
}
But now when you run it, you will see that our string is simply displayed in the console. There is no reading from the keyboard. We replaced the data source. It is no longer the keyboard, but our string!
It's that simple :)
In today's lesson, we got to know a new class and explored a small new hack for working with I/O.
Now it's time to return to the course and complete some tasks :)
See you in the next lesson!
GO TO FULL VERSION