While with incomprehensible format

Asked

Viewed 135 times

5

My knowledge in java is very basic, before that I came across a question to which I have not found answer. The code snippet below is used in some of my applications:

File arquivo = new File("ip.txt");  
FileInputStream fis = new FileInputStream(arquivo);  

while ( (ln = fis.read()) != -1 ) {  
    st += (char)ln;  
}  

fis.close();

But I cannot understand this little passage:

while ( (ln = fis.read()) != -1 ) {  
    st += (char)ln;  
}

Would someone please explain to me what it means?

2 answers

14


You need to understand what expressions are. And that they can be formed by sub-expressions. Java is a reasonably well written language and does not do magic. Everything has a criterion. If you understand these criteria, you can understand anything in the language, even without knowing what it is. That’s the difference between learning to program and following cake recipe.

An instruction while expects a boolean result to decide whether it continues running that code block or not. And this, in this case, is obtained by the operator !=. This operator always returns a booliano, ie, or true or false. Like most operators, it has two operands. And these operands in conjunction with the operator form an expression. One of them is easily identifiable, is the -1 - a literal. The other may seem odd, but it is another expression. Obviously the result of it is that it will be considered as operating. Then this expression needs to be executed first to get the result.

In that expression we find the code (ln = fis.read()). There’s another operator, it’s =, which is the value assignment for a variable. An operand is the ln, the variable (this operator only accepts variable on the left side) and the other, which is the value that will be attributable to the variable is also an (other) expression. The result of this expression is that it will be assigned to the variable. Then it needs to be executed first.

Perhaps it was strange that the attribution is being used as an expression. But it is an expression, it is not a command. So it can be used anywhere that expects an expression. Parentheses are mandatory to avoid any problem of precedence or association of operators.

This expression takes a variable that contains an object and applies the operator . which allows invoking a member of the object, in this case it is a method called read(). It returns -1 if it had nothing else to read. The return of this method will be the result that will be assigned to ln and that will finally be used to compare with the literal -1, producing the booliano expected by while.

This could have been written like this:

ln = fis.read()
while ( ln != -1 ) {  
    st += (char)ln;
    ln = fis.read() //repetição de código que deveria ser canônico
}

Or

while (true) {  
    ln = fis.read()
    if (ln != -1) break; //if horroroso
    st += (char)ln;
}

I put in the Github for future reference.

  • Thanks for the explanation.

7

Basically you are reading a text file character by character and concatenating to a string. This method FileInputStream#read() returns -1 when the end of the file is reached, then what you are doing is going through all the content, character by character while data is being read.

Like FileInputStream implements the interface AutoCloseable, you can use Try-with-Resources and dispense with the call to the method close:

File arquivo = new File("ip.txt");
try (FileInputStream fis = new FileInputStream(arquivo)) {
    while ((ln = fis.read()) != -1) {
        st += (char) ln;
    }
} // O que seria o "close" do FileInputStream.

If there is no need to do something special with each character read (in the code, it is only being concatenated to a string), you can choose to read the entire contents of the file at once without a loop:

String content = new String(Files.readAllBytes(Paths.get("ip.txt")), StandardCharsets.UTF_8);
System.out.println(content);
  • 1

    I will use the second option, I could only read character by character. Thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.