Reading stream from infinite loop - java

I'm trying out some socket programming in Java for a little project. I've ran into a problem reading an infinite InputStream from an external process. The program goes into an infinite loop.
I suspect that readLine() have to read the stream until EOF.
I've put some print statements and I'm sure that the program reaches the while-loop.
This is my method:
public void run() throws IOException {
Process p = Runtime.getRuntime() .exec(exe);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while((line = in.readLine()) != null){
System.out.println(line);
dout.writeUTF(" " + line + " yes!");
dout.flush();
}
in.close();
dout.close();
s.close();
ss.close();
}

As #codeflush.dev mentioned the stream does not reach EOF and readLine is therefore not a viable option.

Related

BufferedReader keeps waiting for response

I have a server and client running on local server.
I read from the server this way:
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
public static String readResponse() throws IOException{
String response = "";
String line;
while((line = br.readLine()) != ""){
System.out.println("s: " + line);
}
return response;
}
And I get the response from server but the program stops and doesn't go anywhere from there:
Please enter option number: 1
c: MSGGET
s: 200 OK
s: Go for it now. The future is promised to no one.
And it just hangs here, when it is suppose to continue.
I also tried:
while((line = br.readLine()) != null){
It just keeps waiting. Is there anything maybe on the server that I have to change to tell the client that I am done transmitting data.
Please help! Thank you!
while((line = br.readLine()) != ""){
System.out.println("s: " + line);
}
return response;
}
Unless your peer is planning to transmit a blank line as an end-of-message sentinel, this loop is pointless, and it also compares Strings incorrectly.
And I get the response from server but the program stops and doesn't go anywhere from there.
It is waiting for an empty line that never arrives. And it is ignoring the end of stream condition.
while((line = br.readLine()) != null){
Now this loop is correct, but it won't exit until end of stream, which won't happen until the peer closes the connection.
It just keeps waiting.
That's what it's supposed to do.
Try this one :
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
public static String readResponse() throws IOException{
String response = "";
String line;
while((line = br.readLine()) != "" || (line = br.readLine()) != null)){
System.out.println("s: " + line);
}
return response;
}
if this is not working then you need to check if you are sending some special character on end of stream from server. Then apply check for that character.
I ended up using this:
while(!(line = br.readLine()).equals("exit")){
And I asked the person responsible for the server to print the following when he is done writing a response:
//this was initiated at the beginning of the program
out = new PrintWriter(socket.getOutputStream(), true);
out.println("exit");
This seems to works well for me so far!
Thank you everyone for your help!

Java InputStream to string

in my java program, i am trying to get the InputStream from a process and print it with this piece of code:
try {
Process p = Runtime.getRuntime().exec("cmd /c start dammage\\4.simulation.cmd");
//BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
//StringBuffer sb = new StringBuffer();
//String line;
//while ((line = br.readLine()) != null) {
//sb.append(line).append("\n");
//}
//System.out.println(sb.toString());
String input = IOUtils.toString(p.getErrorStream());
System.out.println(input);
} catch (IOException ex) {
Logger.getLogger(UI.class.getName()).log(Level.SEVERE, null, ex);
JOptionPane.showMessageDialog(this, "Something happened");
}
I tried both ways shown above (commented and uncommented), but none of them prints anything. So i would like to ask what am i doing wrong here?
I appreciate any help.
The buffered reader solution looks fine. You might be looking in the wrong stream. Try getting from both streams.. Like
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
StringBuffer sb = new StringBuffer();
String line;
//Read the output from the command
while ((line = stdInput.readLine()) != null) {
sb.append(line).append("\n");
}
//read any errors from the attempted command
while ((line = stdError.readLine()) != null) {
sb.append(line).append("\n");
}
Are you sure it should print something? Because, the commented code should work just right provided the command executed is returning non-empty input stream. Try replacing the argument of exec to "cmd". And see if it's able to read from the input stream. Do following. On windows machine it should give you welcome message from cmd (the usual welcome message we get after we run start command prompt).
Process p = Runtime.getRuntime().exec("cmd");
About the uncommented code, How IOUtils work? Does it read from the error stream repeatedly. Because, IMO, it's just one time read and not the repetitive one.
Hope I don't confuse.
You should add a p.waitFor(); to give the program time to terminate. Also, verify if you really want to read stdout or stderr
This works for me:
Process p = Runtime.getRuntime().exec("cmd /c java -version");
int ret = p.waitFor();
System.out.println("process terminated with return code: " + ret);
BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
StringBuffer sb = new StringBuffer();
String line;
while((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
System.out.println(sb.toString());

Looping over InputStream truncating data

So this is a very simple problem with a simple solution that I'm just not seeing:
I'm trying to get a list of data through an InputStream, looping until I reach the end of the stream. On each iteration, I print the next line of text being passed through the InputStream. I have it working but for one small problem: I'm truncating the first character of each line.
Here's the code:
while (dataInputStream.read() >= 0) {
System.out.printf("%s\n", dataInputReader.readLine());
}
And the output:
classpath
project
est.txt
Now, I know what's going on here: the read() call in my while loop is taking the first char on each line, so when the line gets passed into the loop, that char is missing. The problem is, I can't figure out how to set up a loop to prevent that.
I think I just need a new set of eyes on this.
readLine for DataInputStream is deprecated. You may try wrapping it with a BufferedReader:
try
{
String line;
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( dataInputStream ) );
while( (line = bufferedReader.readLine()) != null )
{
System.out.printf("%s\n", line);
}
}
catch( IOException e )
{
System.err.println( "Error: " + e );
}
Also, I`m not sure, that it is a good idea to use available() due to this specification:
* <p>Note that this method provides such a weak guarantee that it is not very useful in
* practice.
Use one BufferedReader and InputStreamReader, here is one example:
InputStream in=...;
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while (br.ready()) {
String line = br.readLine();
}
dataInputStream.read() reads the first character of the InputStream, the same as dataInputReader.readLine() reads the complete next line. Every read character or line is then gone. you can use the dataInputStream.available() to check if the InputStream has data available.
That should print the correct output:
while (dataInputStream.available()) {
System.out.printf("%s", dataInputReader.read());
}
String line;
while ((line = dataInputReader.readLine()) != null) {
System.out.println(line);
}

BufferedReader.readLine() waits for input from console

I am trying to read lines of text from the console. The number of lines is not known in advance. The BufferedReader.readLine() method reads a line but after the last line it waits for input from the console. What should be done in order to avoid this?
Please see the code snippet below:
public static String[] getLinesFromConsole() {
String strLine = "";
try {
// Get the object of DataInputStream
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String line = "";
while ((line = br.readLine()) != null)
strLine += line + "~"; //edited
isr.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
return strLine.split("~");
}
The below code might fix, replace text exit with your requirement specific string
public static String[] getLinesFromConsole() {
String strLine = "";
try {
// Get the object of DataInputStream
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String line = "";
while ((line = br.readLine()) != null && !line.equals("exit") )
strLine += br.readLine() + "~";
isr.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
return strLine.split("~");
}
When reading from the console, you need to define a "terminating" input since the console (unlike a file) doesn't ever "end" (it continues to run even after your program terminates).
There are several solutions to your problem:
Put the input in a file and use IO redirection: java ... < input-file
The shell will hook up your process with the input file and you will get an EOF.
Type the EOF-character for your console. On Linux and Mac, it's Ctrl+D, on Windows, it's Ctrl+Z + Enter
Stop when you read an empty line. That way, the user can simply type Enter.
PS: there is a bug in your code. If you call readLine() twice, it will skip every second line.

Printing multiple lines returned by BufferedReader

I'm writing a program that basically sends linux command through java and then prints back the output. It works fine if the output is one line only but for multiple lines output I can't figure out what I'm doing wrong. For example to check the memory usage I use the "free" command but it only returns lines 1 and 3. Here is my code:
if (clinetChoice.equals("3"))
{
String command = "free";
Process process = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
System.out.println("You Chose Option Three");
String line;
while ((line = reader.readLine()) != null)
{
output += line;
System.out.println(line);
line = reader.readLine();
}
}
When I run this it only returns:
total used free share buffers cached
-/+ buffers/cache: 6546546 65464645
Client Code:
while ((fromServer = input.readLine()) != null)
{
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye"))
break;
System.out.print("Enter your choice: ");
fromClient = stdIn.readLine().trim();
if(fromClient.equals("1"))
{
System.out.println("Client: " + fromClient);
output.println(fromClient);
}
if(fromClient.equals("2"))
{
System.out.println("Client: " + fromClient);
output.println(fromClient);
}
if(fromClient.equals("3"))
{
System.out.println("Client: " + fromClient);
output.println(fromClient);
}
if(fromClient.equals("4"))
{
System.out.println("Client: " + fromClient);
output.println(fromClient);
break;
}
}
You're calling readLine in both your loop test and the body of the loop. So for every iteration of the loop, readLine is called twice, and one of the results is discarded: it isn't printed or added to output. This matches the results that you describe.
This loop should be sufficient:
while ((line = reader.readLine()) != null)
{
output += line + System.getProperty("line.separator");
System.out.println(line);
}
If you're just trying to print the entire output once, and since you're collecting the output in your output variable, you can move the println out of the loop:
while ((line = reader.readLine()) != null)
{
output += line + System.getProperty("line.separator");
}
System.out.println(output);
Simply use this... You are calling the readLine() twice....
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
If you want to assign the data to output varible..then do this inside the while loop..
output = output + line;
I should point out that in addition to the comments re. using readline() twice, you should strictly consume stdout/stderr simultaneously. Otherwise you run the risk of blocking the process output since you're not consuming it. See this SO answer for more info.

Categories