[Last Call] Learn how to a build a cloud-first strategyRegister Now


Streams in java - theoretical points

Posted on 2003-12-09
Medium Priority
Last Modified: 2006-11-17
This is kind of a strange question.  I don't really need a solution, as I've already found one, but I'd like to know some theory behind WHY the solution I've come with works.

A bit of background.  I had an assignment for a programming class that involved graphs.  My professor wrote a program to produce random graphs, that were represented as an n by n matrix, where n is the number of vertices in the graph.  We were to use his program to produce a large number of graphs, and then comment of the degree of connectivity of the vertices, and draw some fairly general conclusions.

Not wanting to do more work than I had to, I tried to write a program automate running his program, to produce the random graphs.  The way his program works is that there's a menu, the user chooses an option, then the program asks the user questions accordingly.  So I used Runtime.exec(), and treated the input and output streams.  All worked well for the choice from the menu, and for the initial questions, but at one point, his program threw a NullPointerException, because it was interpreting its input from my program as being null.  I looked at his code, and realized that it was because, at the point where the NullPointerException was thrown, he was calling a new method to get input.  In the new method, he created a NEW BufferedReader with System.in, instead of passing the method the current BufferedReader from the main method.

Is everyone following so far?  So I modified his code, so that the main passed its BufferedReader to the second method, and all worked well.

My question is, why did that work?  System.in is still System.in, no?  So why, if he made a new BufferedReader with System.in, would it cease to read from the input that I'd already sent it?
Question by:blackwednesday
LVL 16

Accepted Solution

imladris earned 1480 total points
ID: 9905528
HMmm. I'm not sure, of course. But here is a possible explanation.

Assuming the "first" input was also using BufferedReader, it would be "reading ahead" to get as much input as it could (that's what BufferedReaders are for).

In the case where the program is run manually, that would not make any difference. There was no more input, the first BufferedReader couldn't get anymore. The new one gets created, and *then* the user adds input, and so it goes to the new BufferedReader.

However, in the case where you are running it from another program, it may be that the input provided from the controlling program in fact *is* available while the first BufferedReader is still sucking at the system input stream, and so the first one would get it.
By the time the second BufferedReader is created, there is nothing left for it, and a problem ensues.

Author Comment

ID: 9905601
Ah, so the input that has already been caught isn't in System.in anymore, but in the first BufferedReader?

That makes perfect sense.  I'm amazed that I thought of the solution as quickly as I did, considering I didn't really understand it.

So, another question: is it poor programming to use 2 BufferedReaders like that, or is there a real reason to do it?  I would say that maybe my professor did it on purpose, so that we couldn't write a script to run his program more quickly (I wouldn't put it past him to be sadistic like that), but I think he's too lazy to think of it.  Plus, he gave us the source, which is  why I was able to modify it.  He could have just given us the compiled class.

To other experts:  please answer this question if you will, but understand that I like imladris' answer, so unless someone points out to me that it's completely wrong, he's getting the points.
LVL 15

Expert Comment

ID: 9905707
Yes, it is poor programming to use 2 bufferedreaders to read from the same inputstream here. but it might be excuaseable because of other factors.
     Could there be situations where we wanted the inputstreams to be different (read from System.in until GUI is set up, then read from GUI).
Not knowing what he had in mind as 'possible future expansions' it is not possible to give a clear yes/no.

But it is probably just because he reused some old code modules without really considering its functionality.
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.


Expert Comment

ID: 9910643
better yet... ask the professor :)

Expert Comment

ID: 9911728
I do not think that using 2 BufferedReaders on the same stream  is excusable. Think about it for a while .... now why would you  want to create a new object to carry on with the same thing it has been doing for the past who nows how long. Ok I know we have alot of memory and all but hey Java isn't exactly cheap on the stuff. So the saying goes "Share and share alike" rather have two methods/threads/objects whatever have access to a single resource or stream by means of the same object (That would depend on the type of resource though) rather than create a new object and continue reading where the other has left off.

imladris' solution with the BufferedReader is in fact correct. If you would have liked that code of your professor to work other than passing it the already used BufferdReader you would have to close the old reader before the system enteres the method in which the second BufferedReader is used. That will cause the firsts BufferedReader to roll back it's reading to such a state that the buffered data that has not yet been read by the program will still be available to the second BufferedReader.
LVL 15

Expert Comment

ID: 9911802
The key point is "the same thing". If it really is the same thing then yes. but if the second reader could be taking its data from some other input device it should be distinct.

Author Comment

ID: 9913011
Well, yes, having 2 BufferedReaders to read from 2 input devices is necessary.  In this case, though, I think my prof was just lazy  and didn't bother reading over his code to make sure what he was doing made sense (you should see his assignments and exam questions... we just had the final, and there was a question with a class called Person, with a constructor that looked like:
public Poodle(){}
Obviously, he just can't be bothrered.)

LVL 15

Expert Comment

ID: 9913506
Yeah, that is typcal sloppy reuse of code. ( I know, cause I do it myself :-))

Featured Post


Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
Suggested Courses
Course of the Month17 days, 15 hours left to enroll

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question