I have a program that needs to process data from Standard-In. I can call it on the command line like so java program < input. I want to write a proper unit test for its main(). Is it possible to reassociate a method's System.in with some other stream?
In the test, I can read the sample data, and then somehow run the original program with its stdin connected to some stream that i define (from the sample data) and verify that it returns what i expect. I considered using these classes:
PipedInputStream and
PipedOutputStream. But it would require me to modify the original program to read from a PipedInputStream every time I test it. Or I can isolate the stream reading into a function (eg. parseStream(InputStream) ) and pass a PipedInputStream which is already connected to the sample data.
I can also write a shell script to pipe whatever i want into its stdin, but the method in question will be a part of a series of processing steps so it shouldn't itself write to stdout and actually returns ArrayList<SomeCompositeType>. Where SomeCompositeType contains the data that was read in a structured way (eg. some ints, arrays, Maps, etc..)
So is it possible to call some method that reads from System.in with a different stream?
See my comment.
What you appear to want is provided by System.setIn :-)
Related
I tried to understand the logic behind inputstreams and reading from files, but I fail to understand how you can read from a file using an inputstream.
My understanding is that when using input devices like a keyboard, you send input data through the input stream to the system. If you are reading from an input stream, aren't you reading the input data that's being send to the system at that time?
If we are creating an inputstream with the following code:
FileInputStream test = new FileInputStream("loremipsum.txt");
And if we try to read from the newly created inputstream with test.read(); how is there any data flowing through the inputstream? As no inputdata has been input from an input device at the time, but has already been input way beforehand. Is there something I'm missing out on? It almost seems to me as input streams are used in two different ways: Java using inputstreams to read data from a source and input devices using to input data to a source.
Java streams are a general concept / interface - a stream of data that you need to open, then read the data from (or write data to for output streams), then close. The basic stream only supports sequential reading / writing, no random access. Also, the data may or may not be readily available when you attempt to read from the stream, so the read may or may not block.
This abstraction allows us to use the same approach regardless of where we read the data from - it might be keyboard, a file, a network connection, output form another program or even some kind of generator that generates an endless sequence of data. Simply put, reading the input from file behaves the same as if someone in the background opened the file and typed its content on the keyboard really fast.
There are ways in Java to read the file in another ways (e.g. random access instead of sequential), but if you need to read the file from start to end, streams are a useful abstraction.
It seems to me that InputStream and OutputStream are ambiguous names for I/O.
InputStream can be thought of as "to input into a stream", and OutputStream can be thought of as "get output of a stream".
After all, we read from an "input" stream, but shouldn't you be reading from an "output"?
What was the rationale behind choosing these two names and what is a good way to remember Input/Output stream without confusing one for the other?
The streams are named not for how you use them inside your code but for what they accomplish. An InputStream accomplishes reading input from somewhere outside your program (the console, a file, etc.), whereas an OutputStream accomplishes writing an output to somewhere else (again, console, file, etc.). Your Java code is only the intermediary in this scenario: In order to make use of the input, you have to read it from the stream, and in order to produce an output, you first have to write something to the stream.
The problem with the naming is only that streams by design always have something that goes in and something that comes out - you can always read and write on/with any stream. All you have to remember is that they are named for the more important task they do: interacting with something outside your code.
Think of your program/code as the Actor.
When the Actor wants to read something in, it seeks an handle to
InputStream cause its this stream that will provide the Input. And hence when you Read from it.
When the Actor wants to write something out, it seeks an handle
to OutputStream and then start writing to the handle which will do
the rest. Likewise you Write to it.
I hope this answers. I just visualize my code as the classic Stick Diagram Actor and InputStream and OutputStream as the entities with which you interact.
I am very much confused about Streams.
1) Does OS(i.e Windows) provide a Common Standard Input Stream and all the languages use it(i.e. Java refers to it as System.in and same Standard Input Stream is referred with stdin in c)?
Is it like keyboard has some port or physical address and OS has stored that
in some variable and when a program needs that it will give that same address to stdin or System.in depending on the language?
OR,
2) Is it like each language has its own API written for standard streams and when we run the program, a stream will get connected to the input device?
And what information that stream would have apart from data? i.e. Physical Port or address of device or what?
Also, Please tell about what is the meaning of System.in get "connected" to program when we run it. what does "connected" mean here?
Please share some link.
Definitions
A “stream” is a catch-all word, like “window”. All a stream means is that there is some thing (a “device”) that produces sequential data or accepts sequential data.
For example, I can make a string into an input stream (produces data), by simply keeping track of what the next character to produce is. When we run out of characters, we've reached the end of the stream. C++:
struct my_hello_stream
{
static const char* s = "Hello world!";
int n;
my_stream(): n(0) {}
int get()
{
if (s[n]) return s[n++];
return EOF;
}
};
Abstractions
Every system has its own way of abstracting a stream. The OS does it through files, pipes and character devices, which you can open for reading or writing. How exactly this is done depends entirely on the design of the OS. Consult your OS API documentation.
On top of that sits a programming language, like C or C++ or Java or FORTRAN — you name it. The programming language itself also defines a stream in a way convenient for the users of that language. In C you have a FILE*. In C++ you have std::iostreams. In Java you have I/O streams. Whatever the case, this works above the OS stream to read and write data from and to files, etc.
Moreover, these language features often allow you to do more powerful things with these stream interfaces, such as convert the character sequence 1234567 into a native integer value, and to perform these operations over strings.
Beyond that, there are also external libraries that allow us to treat things like internet connections and port connections with the printer like a stream. Some of this stuff the OS handles for us. Some of it it doesn't.
tl;dr
It all depends. What matters is the abstraction you have access to — which is typically your programming language. Hence, read about how your programming language expects you to open a file and read and write data, then act as if that is right. Whatever else actually happens underneath is magic.
What is a stream?
Stream is an abstraction which is either an input source or an output destination. In UNIX for example everything is a file so your keyboard will be represented by a read only file (why?). Whenever you want to read something from keyboard you just use the read system call using the keyboard file as parameter.
Does OS(i.e Windows) provide a Common Standard Input Stream and all
the languages use it(i.e. Java refers to it as System.in and same
Standard Input Stream is referred with stdin in c)?
OS only provides the very basic functionality such as read and write system calls (OS dependent) which can be used to read and write raw bytes. All the programming languages use this basic functionality to create abstractions (such as translating raw bytes to certain character set or buffering the data before writing).
When the program starts executing operating systems opens three standard text stream (channel) automatically and provides constant file pointer for them.
The stream you can think as like a channel, rather than a standard stream we have to open a stream by some library functions like fopen in c, which creates a stream bw your program and the file specified.
I am writing a program in Java and I want it to accept two different methods of input. One would be piping a file into into the program like this: java program < inputFile.txt Another way I want the input is for the program to wait (in the middle of execution) for the command line input by the user before continuing. Also, I want to process the input differently depending on which method was used.
I've checked myself and both types of input come from System.in. Is there any value in System.in that would depend on the method of input used? If not from System.in, is there any other way to derive a value that's input-method dependent?
No, to the program there is no difference whether input is coming from a user's finger or a pipe. There probably are hacks around this, but the main question is why do you care whether it's one or the other?
what is the difference when I use buffer istead of console() for retriving the output from my code?
The Console class, as used by System.console() seems targeted to interactive character-based I/O, as provided by an actual console such as a cmd.exe window in Windows or a terminal in Unix-like systems. As such, the system console may not always be available, depending on the underlying OS and how the JVM was started.
On the other hand, Scanner works with any input stream, including files and the standard input. It is more flexible, but it does not provide some console-specific functionality that Console does, such as the ability to read text - usually passwords - without echoing it back to the console.
The Console class makes it easy to accept input from the command line, both echoed and unechoed. Unechoed means you will see some special character in your console while writing a text (ex. *, ? etc) like when you enter your password in facebook. :) Its format() method also makes it easy to write formatted output to the command line(like making a pyramid of *s or a formatted date and currency formats etc). It also helps to write test engines for unit testing. or you can use it to provide you a simple CLI (Command Line Interface) instead of a GUI (Graphical User Interface) in case you want to create a real simple and small application. And yes, it is also system dependent that means that you cannot always rely on your system to provide you a console instance.
Now about buffering, its actually a technique used in I/O (i.e. both input and output) when you are interacting with a stream (be it a character stream or byte stream, be it from a console or a socket or a file). Its basically used to speed up the I/O and save system resources by avoiding multiple call to read() and write() methods. It is suggested that you use it in almost every kind of I/O interaction.