Reputation: 49107
I have been reading about streams in Java the past days. After reading quite a bit I start to understand that the name "stream" was chosen because of similarity to what we use the word about in "real life" such as water. And that it is not necessary to know where the data comes from. Please correct if I have interpreted it wrong.
But I do not understand this. When I say getOutputStream
or getInputStream
on a socket for example I get a InputStream
which I can chain to whatever I like. But isn't the InputStream/OutputStream abstract classes? I don't know exactly how to explain it properly but I do not understand that a socket connection just by invoking that method automatically has a stream/channel where bytes/characters can flow? What is in fact a InputStream / OutputStream? Are streams a way of abstracting the real sources?
I think I understand the various ways of chaining them though, however I feel I miss the core of the concept.
In lack of a proper way of explaining it I will delete question if it is bad.
Thank you for your time.
Upvotes: 2
Views: 200
Reputation: 4758
I don't think this is a bad question. You're quite right that streams abstract away from you the complexity of where the data is coming from and make it uniform. Therefore you can write code that reads from a File or a Socket and that code could look almost identical. It means you generally have to write less code.
When you get the InputStream from a Socket you are able to access any data arriving at that socket. When reading from this stream, typically, you supply a byte array and ask the stream to fill it for you. It will read as much data as is available or it will fill the buffer. It's the up to you what you do with the data in this byte array.
For any kind of Socket IO though, having said all this about Streams, the Java socket API is quite old and there are some really good alternatives available which wrap it and are easier to use. I highly recommend Netty using which you can forget about streams and focus on POJOs and how to encode and decode them.
Upvotes: 3
Reputation: 341003
InputStream
/OutputStream
are, well, abstractions. They give you some basic API for reading/writing bytes or groups of bytes without exposing the actual implementation. Let's take OutputStream
as an example:
OutputStream
receives a bunch of bytes through the public API. You don't actually know (and care) what is happening with these bytes afterwards: they are sent. Real implementation may: append them to file, ignore them (NullOutputStream
in Apache Commons), save them in memory or... send through socket.
This is what happens when you call Socket.getOutputStream()
: you get some implementation of OutputStream
, just don't care, it is implementation-dependent and specific. When you send bytes to this stream, underlying implementation will push them using TCP/IP or UDP. In fact TCP/IP itself is a stream protocol, even though it operates on packets/frames.
The situation is similar for InputStream
- you get some implementation from socket. When you ask the stream for few bytes, the underlying InputStream
implementation will ask OS socket for the same amount of bytes, possibly blocking. But this is the real fun of inheritance: you don't care! Just use these stream any way you want, chaining, buffering, etc.
Upvotes: 3
Reputation: 597412
InputStream
is indeed an abstraction. On each occasion a different implementation of the stream concept can be used. But the user of the stream does not need to know what was the exact implementation.
In the case of Socket
, the implementation is a SocketInputStream
which extends FileInputStream
Upvotes: 3
Reputation: 234857
When you call getInputStream
, the socket returns an instance of some concrete subclass of InputStream
. Usually you don't worry about the exact class of the returned object; since it is an InputStream
, you just work with it that way. (The subclass may even be a private nested class of the socket class.)
Upvotes: 3