CodeGym /Courses /Java Core /Write your own stream: a wrapper for System.in

Write your own stream: a wrapper for System.in

Java Core
Level 8 , Lesson 7
Available

"Hello, Amigo! Today we'll explore some super interesting stuff: how to replace System.in input stream."

System.in is a simple static InputStream variable, but you can't simply assign a new value to it. But you can use the System.setIn() method.

First, we need to create a buffer, and then put some values into it. Then we'll wrap it in a class that knows how to read data from the buffer using the InputStream protocol.

This is how it looks:

Code
public static void main(String[] args) throws IOException
{
 //Put data into a string
 StringBuilder sb = new StringBuilder();
 sb.append("Lena").append('\n');
 sb.append("Olya").append('\n');
 sb.append("Anya").append('\n');
 String data = sb.toString();

 //Wrap the string in a ByteArrayInputStream
 InputStream is = new ByteArrayInputStream(data.getBytes());

 //Replace in
 System.setIn(is);

 //Call an ordinary method that doesn't know about our changes
 readAndPrintLine();
}

public static void readAndPrintLine() throws IOException
{
 InputStreamReader isr = new InputStreamReader(System.in);
 BufferedReader reader = new BufferedReader(isr);

 while (true)
 {
  String line = reader.readLine();
  if (line == null) break;
  System.out.println(line);
 }
 reader.close();
 isr.close();
}

"Bilaabo! This is the most interesting example I've seen. I didn't know you could do that. Thanks."

"You're welcome, Amigo."

Comments (21)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Karas Level 1, Tampa, United States
5 April 2021
A random question, what is better then, BufferedStreamReader or this? I get it this is to show us an example of a wraper but WHY???!
Gellert Varga Level 23, Szekesfehervar, Hungary
29 June 2021
I only understood the "why" from the comments of fellow students below. In short: How to swap the default meaning of System.in input stream for something else. With the purpose to a ready-made program that would expect input from the keyboard can be able to get the expected data from somewhere else. For purpose of program testing.
Sela Level 20, Poland
28 August 2020
setIn reassigns the standard input stream. the standard input stream means System.in - a variable of System class (set to keyboard device by default). System.in variable is swapped for InputStream is and now InputStreamReader reads from new stream, giving the output

Lena
Olya
Anya
you will find more in this post
Dave Andrea Level 41, Canada
21 July 2020
For those who have not learned about StringBuilder yet, it is basically a class used to make mutable strings. When you concatenate strings, a new string is made and the old strings are used to form it. There's some overhead to this process. StringBuilder strings can be changed, so adding stuff to the end of them is more efficient.
fzw Level 41, West University Place, United States
11 April 2020
How does this work as a "wrapper for System.in"?
Johannes Level 27, Centurion, Pretoria, South-Africa
8 April 2020
So you're actually setting a String as the "new" System.in ? That could for example be useful if you don't want to create a file, but want to read user input, and then later remember and iterate through it again. (Append each input to a stringbuilder object, assign it to a string, then assign the string to System.in)
yehuda b Level 23, Beersheba, Israel
18 August 2020
Why wouldn't you just iterate through the String itself without changing System.in? there are many ways to iterate through Strings (toCharArray, subString, etc.)?
Andrei Level 41
15 January 2021
Johannes, are you Henk? Or is Henk Johannes? 😂 Please see below what I mean.
Jason Level 26, Rancho Cucamonga, United States
6 October 2019
I take it that append() is another thing that CodeGym is going to use without tell us what in the hell it is?
Andrei Level 41
15 January 2021
You betcha! 😁
Evgeniia Shabaeva Level 40, Budapest, Hungary
16 August 2024
append() is a method of the StringBuilder class (I know I'm terribly late with this comment:)).
Jen P Level 26
5 August 2019
Is there any reason/scenario we should replace System.in in this way? or it is just to complete our Java knowledge?
Vesa Level 41, Kaliningrad, Russia
29 January 2020
This may be necessary when testing methods for outputting data to the console. I mean using the JUnit library for example.
Onur Bal Level 27, Istanbul, Turkey
22 September 2020
This is actually how the CodeGym verifier works with our tasks where we make use of "System.in" for user input. Instead of having someone at CodeGym manually enter strings into the console each time a member submits a task, "System.in" is replaced with strings from a file, and those are fed into the programme, instead of actual console input. A similar approach may prove useful in the future when you wish to run similar tests.
Andrei Level 41
15 January 2021
Excuse me, I believe it's called the g-g-g-g-G-UNIIITTTT !
Ewerton Level 30, Belo Horizonte, Brasil
3 July 2019
It doesn't sound useful.
Henk Level 19, Pretoria, South-Africa
6 June 2019
why not just put the data in the String in the first place, instead of first putting it in a StringBuilder ? String data = "Lena" + "\\n" + "next name" etc. Or data.concat ?
VIVEK BARUAH Level 20, Eluru, India
10 June 2019
exactly just using a new Class out of the blue for doing the simplest thing does'nt make sense.
zhaoyang Level 25, Los Angeles, United States
28 June 2019
I think it's also a buffer example for Using StringBuilder
Darko Jakimovski Level 18, Kriva Palanka, Macedonia, The Former Yugoslav Republic of
25 September 2019
String is immutable while StringBuilder is not, that's the main difference that I realized wasn't put in this course. Which is a big miss! A new String object is created on heap each time you concatenate it while StringBuilder uses the same object and just adds to the end of it in this case. Finnaly saves it as String.
Juanf Level 26
11 October 2019
Maybe it is just taking the opportunity to teach something little new ¯\_(ツ)_/¯