Tanner Summers
Tanner Summers

Reputation: 663

Questions on Java's I/O Classes

I am reading up on this tutorial on networking (client/server) in java and I had a question about something I don't understand.

https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html

I been seeing this often enough

BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

and

BufferedReader inputStream = new BufferedReader(new FileReader("xanadu.txt"));
PrintWriter outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));

I know that constructor for the BufferReader is

BufferedReader(Reader in)

1) I also know since InputStreamReader is inherited by the Reader class, that you can pass it through the BufferedReader constructor. But my question is why do we need the InputStreamReader? Is it because the InputStreamReader can hold a inputstream (according to it's constructor in the API)

Edit: made mistake on my part, please ignore this

2) Now for the next part, inputStream & outputStream (according to the API) are inherited from the Object class. How do those two classes can be allocated as BufferedReader and PrintWriter respectively. Is this because they both are inherited by the object class, or is their another reason? Because if this is the case, how would anyone know what you can allocated as class as if everything is suppose to be inherited by the Objects class.

3) Last but not least, another question about the BufferedReader and PrintWriter here

BufferedReader inputStream = new BufferedReader(new FileReader("xanadu.txt"));
PrintWriter outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));

why did those two classes, choose to pass through a reference of the FileReader and FileWriter classes?

I guess I want some more info on why these specific classes were chosen.

Thanks in advance!

Upvotes: 0

Views: 429

Answers (2)

user4948585
user4948585

Reputation:

OK, Here is simple reason

This is decorator design pattern. You take a basic object and keep on adding required decorations on top of it. Example: Pizza with 2 toppings ( i am hungry now)

You do this because it reduces the number of different classes needed (InputStreamReader * Buffered/UnBuffered * bla bla bla results in many different combinations so if we have one child class for each combination, it will be 100+ stream classes and we will be confused, so we simply decorates it ( all types have same interface and we pass each other in constructor)

If still in doubt just google decorator pattern for details

Upvotes: 0

Amadan
Amadan

Reputation: 198294

1) To construct BufferedReader, you need a Reader parameter. System.in is not a Reader. Each part of the Java IO puzzle does only one thing: InputStreamReader gets you a Reader from an InputStream, then BufferedReader buffers that Reader.

2) They can't, precisely because of #1. First you wrap the InputStream in a Reader or Writer wrapper, then you can do other stuff.

3) Because they are reading from / writing to a file, not a stream. (EDIT: and, as pvg mentioned in comments, inputStream = new BufferedReader(...) and outputStream = new PrintWriter(...) are extremely confusing variable names.)


Basically, it's like a manufacture. You have System.in, which is an InputStream. That means he is handing you plain bytes. You don't want plain bytes; you want to be given characters (i.e. bytes parsed by some character encoding, such as, e.g. UTF-8). But InputStream doesn't know how to do that.

Enter InputStreamReader. As every Reader, he knows how to give you characters. Specifically InputStreamReader knows how to get bytes from an InputStream and hand it off as characters. So you put him in line just in front of System.in, so you don't have to deal with him.

But you don't want to get each character one at a time. You want more. You want to be able to read a whole line at once! You want... a buffer! Enter BufferedReader: he's the guy who stands in front of another Reader, collects each character and hamsters it away till you ask for some of it.

To see exactly what is going on, you need to understand the critical distinction between byte-based IO and text-based IO, and study each class' constructor function to see exactly what kind of thing it wraps (although names are a good hint).

Upvotes: 6

Related Questions