Reputation: 455
In Java
, the maximum value that a byte
can hold is 127, which is 8 bits. Also, the read() method that FileInputStream
uses (which it inherits from InputStream
) states that it only reads one byte
, and the write() method that FileOutputStream
uses (which it inherits from OutputStream
) states that it only writes one byte
. However, when I pass a number greater than 127 but less than 256 to write() and then read() it, I get a character with a decimal value that is indeed between 127 and 255. This seems to show that write() can actually write 9 bits instead of 8, and that read() can actually read 9 bits instead of 8. So, my question is how is this possible? How can read() read more than a byte
and how can write() write more than a byte
? Is there something else I'm missing?
As a further example, say I pass the integer 1000 to write(). write() then outputs a character, which read() then reads as having a decimal value of 232. This seems to occur because 1000 - 512 - 256 = 232, which again seems to show that write() and read() write and read 9 bits (up to 255) rather than a byte (8 bits, of up to 127). As it seems to me, write() is writing the lower 9 bits of 1000, which read() then reads, which in this case gives 232.
I have posted the program I'm using to test this all out. Also, I am fairly new to Java
, so any help or thoughts are much appreciated!
import java.io.*;
public class TestingCharsAndBytes
{
public static void main(String[] args)
{
FileOutputStream output = null;
FileInputStream input = null;
try
{
output = new FileOutputStream(".../testFileIO1.txt");
input = new FileInputStream(".../testFileIO1.txt");
// Stuff to try:
doFileResult(512,output,input);
doFileResult(128,output,input);
doFileResult(256,output,input);
doFileResult(257,output,input);
doFileResult(160,output,input);
doFileResult(289,output,input);
doFileResult(1000,output,input);
doFileResult(2000,output,input);
}
catch(IOException e)
{
System.out.println("Error occurred.");
e.getStackTrace();
}
finally
{
try
{
output.close();
input.close();
}
catch(Exception e)
{
System.out.println("Error closing file.");
}
}
}
public static void doFileResult(int toWrite, FileOutputStream outStream, FileInputStream inputStream) throws IOException
{
System.out.println("******************");
outStream.write(toWrite);
int x = inputStream.read();
char y = (char) x;
System.out.println("Integer passed to write: " + toWrite);
System.out.println("Input integer read: " + x);
System.out.println("Input character read (after casting to char): " + y);
System.out.println();
}
}
Upvotes: 1
Views: 713
Reputation: 140319
Per the documentation, read()
uses -1 as a special value to indicate EOF. If the actual range of byte (-128..127) were used, -1 would be a valid byte.
As stated in the documentation of the base method, InputStream.read()
:
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.
The idiomatic way to write code reading from a stream is something like:
while (true) {
int v = stream.read();
if (v == -1) {
break;
}
byte b = (byte) v;
// Do something.
}
The cast to byte will "correctly" map the int 0..255 into the byte -128..127, because a narrowing cast from 32 to 8 bits will simply keep the 8 least significant bits.
Upvotes: 3