2

So, I had to take a test for a job interview where I was required to write a mini app that performed simple XOR encryption, and came across this question. I used a FileInputReader to pull each byte in, perform an XOR operation with the key, and pushed the result back out a FileOutputStream. Heres what got me thinking.

FileInputStream returns an int, a 32-bit signed type. When receiving only one byte, you can cast it into a 'byte' type. FileInputStream also returns -1 if it reaches EOF. But, -1 == 0xff in two's complement binary, so what if the byte read is really 0xff, not EOF?

Is 0xff a byte that mathematically won't ever be returned except in special cases (such as EOF)? Or is this a situation that you may have to account for depending on the data you are reading?

Kirk Woll
  • 76,112
  • 22
  • 180
  • 195
Ron Brown
  • 21
  • 1
  • 2

4 Answers4

13

No, -1 in an int is not 0xff, but 0xffffffff. An int is 32 bits in Java.

Before casting the value to byte, check if it is -1.

The API documentation of the read method of class FileInputStream explains this:

Reads the next byte of data from this input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

So, if a byte with the value 0xff is found in the input, the read method will return an int with the value 255 (0xff). Only on EOF will it return -1 (which is 0xffffffff when stored in an int).

Jesper
  • 202,709
  • 46
  • 318
  • 350
2

You could:

int value = is.read();
if (value == -1)
   // the end!
else
{
   byte b = (byte) value;
   // use b
}

Anyway I should use chunk reads (try to read to a byte array) and if the returned byte count is zero, then we are finished:

int count;
byte[] buffer = new byte[8192];
while ((count = is.read(buffer)) > 0) {
   // use buffer from pos 0 to pos count-1
}
helios
  • 13,574
  • 2
  • 45
  • 55
1

0xff is only -1 in base 256, you're working in base 2^32 so there is no confusion. Even if you wrote (signed char)-1 (yes I know that's not valid Java, bear with me), it still ends up written as 0xff.

You can safely assume that any negative return is an error, and normal byte values are what's written in the file verbatim.

Blindy
  • 65,249
  • 10
  • 91
  • 131
0

Read method is not implemented in FileInputStream class, it must have a os specific implementation, which will tell how actually EOF handling is checked.

Ankur
  • 788
  • 6
  • 13