Monday, July 24, 2017

InputStream#read() return an int and not a byte or char?

End of Stream

If the read() method returns -1, the end of stream has been reached, meaning there is no more data to read in the InputStream. That is, -1 as int value, not -1 as byte or short value. There is a difference here!
When the end of stream has been reached, you can close the InputStream.
@reference_1_tutorials.jenkov.com
Java IO: InputStream

Answer1:
Because a byte can only hold -128 until 127, while it should return 0 until 255 (and -1 when there's no byte left (i.e. EOF)). Even if it returned byte, there would be no room to represent EOF.
A more interesting question is why it doesn't return short.
Answer2:
It returns an int because when the stream can no longer be read, it returns -1.
If it returned a byte, then -1 could not be returned to indicate an error because -1 is a valid byte. In addition, you could not return value above 127 or below -128 because Java only handles signed bytes.
Many times when one is reading a file, you want the unsigned bytes for your processing code. To get values between 128 and 255 you could use a short, but by using an int you will align the memory registers with your data bus more efficiently. As a result, you don't really lose any information by using an int, and you probably gain a bit of performance. The only downside is the cost of the memory, but odds are you won't be hanging on to that int for long (as you will process it and turn it into a char or byte[]).

@reference_2_stackoverflow
Why does InputStream#read() return an int and not a byte?

Java doesn't have unsigned types. read() returns unsigned byte and the only way to represent it in Java is to use int type.
byte values are in -128..127 range, while unsigned byte has values in 0..255 range.

InputStream.read() have to return 256 valid values + 1 invalid value as indication of end-of-stream. 257 values in total. Java's byte can hold only 256 values. That is why they used int: 0..255 represents valid byte values, -1 used for end-of-stream.
@reference_3_stackoverflow 
why return type of read() is integer?


/*
 * 字节流和字符流的read()方法为什么返回的是int类型?而且为什么用-1作为判断是不是流末尾?
 */

package cn.itcast.day_16;
import Java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class ReadMethodDemo {
 public static void main(String[] args) throws IOException {
  FileReader fr = new FileReader("src.txt");
  fr.read();   

                            
  /*
   * 如果返回char, 那么无法表示流末尾.
   * char的取值范围是从0到65535
   * 这个范围内的所有字符, 都有可能在数据中出现
   * 我们需要使用一个不可能在数据中出现的值来表示流末尾
   * 那么Java中就是用-1来表示这个末尾的, 因为-1不会在数据中出现
   * 而为了返回-1, 那么只能用int
   * 当流中读取到一个字符时, read()方法内部就会当作int返回, 如果读到流末尾, 直接返回-1
   */
 
  FileInputStream fis = new FileInputStream ("src.jpg");
  //fis.read();     

                         
  int b;
  while((b = fis.read()) != -1)
   System.out.println((byte)b);               //打印的结果全是正数
 
  /*
   * 如果返回byte, 同样无法表示流末尾.
   * byte的取值范围是从-128到127
   * 这个范围内所有的数据, 都有可能在数据中出现
   * read()方法需要返回一个特殊的值来表示流末尾, 这个值不能和流中的数据重复
   *
   * 字符流中读取到的char是直接当作int使用, 例如读取到一个'a'也就是97的时候, 那么就相当于返回了一个int的97
   * 字节流中不能这么做, 因为如果文件中存在数据-1, 把-1直接当作int返回还是-1, 那么就无法区分这个读到的结果是流末尾还是流中的数据了
   *
   * read()方法内部将读取到的所有字节高位补0转为int返回, 这样做所有的数据都会是正数
   * 这时就可以用-1表示流末尾了
   * 而改变后的数据只要强转回byte, 就可以得到原有数据
   */
 }

}

@reference_4_blog.csdn.net
Java中字节流和字符流的read()方法为什么返回的值是int类型 
 
 

No comments:

Post a Comment