Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

These methods are often used to read a byte or character from a stream. Unfortunately, many programmers prematurely convert the resulting int back to a byte or char before checking whether they have reached the end of the stream (signaled indicated by a return value of -1). Programs must check for the end of stream (e.g., -1) before narrowing the return value to a byte or char.

This rule applies to any InputStream or Reader subclass that provide provides an implementation of the read() method. This rule is a specific instance of rule NUM12-J. Ensure conversions of numeric types to narrower types do not result in lost or misinterpreted data.

...

This noncompliant code example casts the value returned by the read() method directly to a value of type byte and then compares this value with -1 in an attempt to detect the end of the stream. This conversion leaves the value of c as 0xFFFF (e.g., Character.MAX_VALUE) instead of -1. Consequently, the test for the end of stream never evaluates to true (because the char type is unsigned and the value of c is 0-extended to 0x0000FFFF).

Code Block
bgColor#FFcccc
FileInputStream in;
// initialize stream 
byte data;
while ((data = (byte) in.read()) != -1) { 
  // ... 
}

...

Use a variable of type int to capture the return value of the byte input method. When the value returned by read() is not -1, it can be safely cast to type byte. When read() returns 0x000000FF, the comparison will test against 0xFFFFFFFF, which evaluates to false.

...

This noncompliant code example casts the value of type int returned by the read() method directly to a value of type char, which is then compared with -1 in an attempt to detect the end of stream. This conversion leaves the value of c as 0xffff 0xFFFF (e.g., Character.MAX_VALUE) instead of -1. Consequently, the test for the end of stream never evaluates to true (because char type is unsigned and the value of c is 0-extended to 0x0000FFFF).

Code Block
bgColor#FFcccc
FileReader in;
// initialize stream 
char c;
while ((c = (char) in.read()) != -1) { 
  // ... 
}

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="32aba06b27a67563-72b98f5b-48914332-becfb50b-9279281f4caba300a0bf9ce2"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

Class InputStream

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="1b1de17122224c51-177a16d7-4af44e1a-8df8a390-f79bb8aec082edff3fc34f22"><ac:plain-text-body><![CDATA[

[[JLS 2005

AA. Bibliography#JLS 05]]

[§4.2

http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2] Primitive Types and Values

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="5abc59a1654f6597-f57df1d4-4fa44a24-8bdc8520-f7ce0da455a08666c53157dc"><ac:plain-text-body><![CDATA[

[[Pugh 2008

AA. Bibliography#Pugh 08]]

Waiting for the End

]]></ac:plain-text-body></ac:structured-macro>

...