Printing multiple lines returned by BufferedReader - java

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.

Related

Reading stream from infinite loop

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.

Running Pig command using JAVA and UNIX

I am trying to run a UNIX command through JAVA. My shell command call a pig script.When i do this excersize in unix terminal it works fine, but through java I didn't get any output.
PFB the code JAVA:
public String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
System.out.println("process started");
p = Runtime.getRuntime().exec(command);
//p.waitFor();
System.out.println("before reader");
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
//String line = "";
System.out.println("After reader ");
while (reader.readLine() != null) {
System.out.println("inside while loop *******************************");
output.append(reader.readLine() + "\n");
System.out.println(reader.readLine());
}
System.out.println("while loop endedr");
} catch (Exception e) {
e.printStackTrace();
System.out.println("inside exception");
}
return output.toString();
}
pig_command :
time pig -param indir="/home/********/INDIR/archived/Bookings/20160620*/part*" -param outdir="/home/*********/OUTDIR/HOURLYBOOKING/20160620/05" -stop_on_failure -x mapreduce /home/directory/pig/pigscript.pig
How i am running java program :
java -cp /home/directory/java_jar.jar com.Example.Tester pig_command
Problem: though the output is getting generated successfully in HDFS the code in the above while loop prints nothing(which should print the job logs).
each call to readline() goes to next line in stream. while loop in your code is omitting two lines in each readline() call (System.out.println and output.append...) so if output of your pig script is only one or two lines then nothing will be printed on console or appended on StringBuffer (output) from while loop.
To fix this... your implementation of
//String line = "";
System.out.println("After reader ");
while (reader.readLine() != null) {
System.out.println("inside while loop *******************************");
output.append(reader.readLine() + "\n");
System.out.println(reader.readLine());
}
should be:
String line = null;
System.out.println("After reader ");
while ((line = reader.readLine()) != null) {
//System.out.println("inside while loop *******************************");
output.append(line + "\n");
System.out.println(line);
}

Properly disconnect client (telnet) from ServerSocket

I want a simple server socket to accept a client and read some texts and disconnect the client from itself. As a client I'm using a telnet for now, because in the future I will create a custom program.
ServerSocket ss = new ServerSocket(SERVER_SOCKET_PORT);
Socket s = ss.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
while (true) {
line = reader.readLine();
if (line == null || line == "" || line == "q") {
log("-- breaking the loop");
break;
}
printf("**%s%n", line);
}
reader.close();
s.close();
ss.close();
The problem I'm having is the while loop never breaks.
First, that isn't how you compare String(s) for equality. Second, I would prefer String.isEmpty() to testing for equality with "". Finally, you can use a try-with-resources to close everything. Something like,
try (ServerSocket ss = new ServerSocket(SERVER_SOCKET_PORT);
Socket s = ss.accept();
BufferedReader reader = new BufferedReader(
new InputStreamReader(s.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.isEmpty() || line.equalsIgnoreCase("q")) {
System.out.println("-- breaking the loop");
break;
}
System.out.printf("**%s%n", line);
}
} catch (Exception e) {
e.printStackTrace();
}
while (true) {
line = reader.readLine();
if (line == null || line == "" || line == "q") {
The problem I'm having is the while loop never breaks.
So the peer never
closes the connection
sends an empty line that compares to "" via the (incorrectly applied) == operator
sends a string consisting only of "q" plus a line terminator.
The normal way to write this loop would be:
while ((line = reader.readLine()) != null)
{
if (line.isEmpty() || line == "q") {
log("-- breaking the loop");
break;
}
printf("**%s%n", line);
}
But if the peer never closes the connection or sends the "q" there's no way this loop will ever exit. Are you sending anything that would produce either of those conditions?
disconnect the client from itself
This is meaningless. Please restate.

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!

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.

Categories