what exactly if ((i = fis.read()) != -1) means in this program?

Viewed 1142
package IO;
import java.io.*;
public class test {

public static void main(String[] args) throws IOException {
    File f1 = new File("C:\\Users\\rs\\New folder\\myname.txt");
    try {
        FileInputStream fis = new FileInputStream(f1);
        int i = fis.read();     
        System.out.print((char)i);
        while((i = fis.read())!= -1) {
            System.out.print((char) i );
        }
        
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    

 }

}

I am a new java programmer and i have a trouble in this code. This code reads bytes from my file (f1) and I can cast this bytes to char and print them, but something is here that I do not understand and its the condition in my while loop. What it exactly means? I mean what exactly if ((i = fis.read()) != -1) means??? And the second question is why we put i = fis.read() in a paranthesis??? My file has a text (1 line) in it.

4 Answers

First Question

That means you would continue reading from the stream until you reached the end. When fis.read() returns -1, that means that you reached the end of the stream and there is no more data to read.

Second Question

i = fis.read() != -1

You might get the impression that the compiler does not know the proper order of execution and there are two scenarios:

  • We check fis.read() != -1 (boolean result) then assign it to i
  • We get fis.read() and assign it to i then check i != -1

But java has well-defined rules, there is only one because of operator precedence.

See the table at: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

Assignment has a lower precedence than !=, so definitely the first scenario will happen. But that is not what we want. (We don't want i to be the boolean result of fis.read() != -1)

Also see: https://introcs.cs.princeton.edu/java/11precedence/#:~:text=Java%20has%20well-defined%20rules,be%20overridden%20by%20explicit%20parentheses.

"Precedence rules can be overridden by explicit parentheses"

So we explicitly put the parentheses to make sure the statement inside it (i = fis.read()) is executed first and the second scenario happens.

FileInputStream 's read() method follows this logic:

Reads a byte of data from this input stream. This method blocks if no input is yet available.

The method will return:

The next byte of data, or -1 if the end of the file is reached.

So -1 is its flag for the EOF check. With this in mind, this code snippet

while((i = fis.read())!= -1) 
      System.out.print((char) i);
  

Is telling that:

1. Assign fis.read() to the var i

2a. If i != -1, print the ASCII char representing the integer just read from the inputstream, and continue the loop.

2b. If i == -1, end the loop / stop reading, because it reached the end of file.

It means

"read until the find the end of file char".

And for the second question:

while((i = fis.read())!= -1) {
    System.out.print((char) i );
}

The (i = fis.read()) defines that "i variable" for the print below while check if it's different from -1.

You can think of (i = fis.read())!= -1 as doing two separate things.

First i = fis.read() is executed. That is, you read a byte from the input stream. If there is nothing to read then i is set to -1.

Second this comparison happens: i != -1 If that is true the loop continues. If that is false the loop ends.

Related