Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing line when reading using input stream reader

Tags:

java

runtime

I have a sample EXE which prints below output.

EXEs Output:

1
2
3
4
5
Failed

equivalent code in java:

for (int i = 1; i <= 5; i++){
     System.out.println(i);
}
System.out.println("Failed");

When trying to initiate the EXE using java code and read the output some data goes missing.

Find the java for initiating the asset.

Java Code:

String[] commands = new String[] {"sample.exe" };
p = Runtime.getRuntime().exec(commands);
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while  ((line = br.readLine()) != null) {
    line = br.readLine()
    System.out.println(line);
    if(line.toLowerCase().contains("failed")){
           #Apply business Rule.
    }
}

Output:

1
3
5

From above output it is clear that we are missing data like 2,3,5,failed.

I think the asset gets completed before we read using InputStreamReader. Is there any way we can make the asset wait till we read using InputStreamReader and begin the next set of instruction or is there any other more better way to do this.

Edit1:

In my original code I am also reading the error stream in parallel please find the code.

ErrorStreamReader:

public void run () {
    try {

        InputStreamReader isr = new InputStreamReader (is);
        BufferedReader br = new BufferedReader (isr); 
        while (true) {
                String s = br.readLine ();
                System.out.println(s+"error Stream");
                if (s == null) break;
            }

    is.close ();    
    } catch (Exception ex) {
        System.out.println ("Problem reading stream " + name + "... :" + ex);
        ex.printStackTrace ();
    }
}

EXE executer java code:

String[] commands = new String[] {"sample.exe" };
p = Runtime.getRuntime().exec(commands);
Thread errorStream = new Thread(new ReadStream("stderr", 
    p.getErrorStream ()) # Reads error Stream In parallel
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while  ((line = br.readLine()) != null) {
    line = br.readLine()
    System.out.println(line);
    if(line.toLowerCase().contains("failed")){
           #Apply business Rule.
    }
}

It looks like the input stream reader is reading by skipping one line at a time.

EDIT2:

Since I was under the thought that InputStreamReader was missing even number lines I made a change in the EXE (a python script) to print from 1 to 6 and then failed.

Modified EXE Output:

1
2
3
4
5
6
Failed

Now the InputStreamReader output was

Java Output:

1
3
5
Failed

As I thought I am missing odd numbered lines. Could somebody please let me know the cause?.


Note:

The problem was due to reading the inputStream Twice sorry for the inconvenience caused. I am extremely sorry.

like image 947
The6thSense Avatar asked Nov 17 '16 12:11

The6thSense


People also ask

What is the difference between input stream and reader?

Reader is Character Based, it can be used to read or write characters. FileInputStream is Byte Based, it can be used to read bytes. FileReader is Character Based, it can be used to read characters. FileInputStream is used for reading binary files.

What is the use of input stream reader?

An InputStreamReader is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified charset . The charset that it uses may be specified by name or may be given explicitly, or the platform's default charset may be accepted.

What is system in in new input stream reader system in?

System. in is an object of InputStream which receives the data in the form of bytes from the keyboard. Then the task of reading and decoding the bytes into characters is done by the InputStreamReader. By the act of reading from System.


1 Answers

The problem was due to reading the inputStream twice

while  ((line = br.readLine()) != null) {
    line = br.readLine() # input stream read here twice
    System.out.println(line);
    if(line.toLowerCase().contains("failed")){
           #Apply business Rule.
    }
}

Hence the problem. To solve it I only read inputStream once.

while  ((line = br.readLine()) != null) {
    System.out.println(line);
    if(line.toLowerCase().contains("failed")){
           #Apply business Rule.
    }
}
like image 97
The6thSense Avatar answered Sep 29 '22 01:09

The6thSense