我查询了InputStream的api,关于read()方法的说明是:返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。我的问题:一个字节可以表示的范围是-128 --- +127为什么api上说读到的范围是0-255,还有就是read是根据什么判断到了流的末尾的,他的结束标记是什么。
现在我已经知道为什么是反255了,原因是返回int符号位转变的原因,现在就问怎么判断刘末尾的,以及
System.out.println("a"+"\r"+"b");
System.out.println("a"+"\n"+"b");
System.out.println("a"+"\r\n"+"b");//效果为什么一样?
ByteArrayInputStream听着名字就是个包装类,其实这些包装类底层都是用的字节流,只不过里面搞个个数组做为缓冲以加强io的性能,那么底层流往数组里按照角标来填充数据,问题的关键在于从源里读的过程是怎么判断读完的,你的回答是在说包装类是怎么添满缓充的,和我的问题没对上,关于换行符的确实如你所说没错。
追答不,InputStream并不仅仅是为IO设计的,InputStream仅仅是字节流而已。ByteArrayInputStream这个类是InputStream的子类,其目的是将byte[]当做字节流来处理,和IO没有关系,这个类里面,实际上就是一个数组,只不过以字节流的形式访问。
我不太清楚你所指的包装类是什么,你可能用错了名词。我所知道的包装类指的是将int,long等包装成Integer,Long这样的包装类。
我说的是字节流的所有子类,sun在设计的时候就是通过包装设计模式设计的,包装设计模式就是把个祖宗类包装起来加强他的功能。
追答哦,你说的是这个包装。
首先你应该意识到,InputStream这个类是一个抽象类,其中read()方法是这样的:
public abstract int read() throws IOException;
这个方法的具体实现,都不仅仅是加强了,而是完全依赖于其子类的实现方法。
事实上,InputStream本身几乎没有提供任何有意义的方法实现。
你可以看到ByteArrayInputStream 的代码是这样的:
public class ByteArrayInputStream extends InputStream {
....
protected byte buf[];
protected int pos;
public ByteArrayInputStream(byte buf[]) {
this.buf = buf;
this.pos = 0;
this.count = buf.length;
}
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
....
}
这里事实上就和IO完全没有任何关系了。
而FileInputStream的read则是:
public native int read() throws IOException;
这样调用了JNI。这里的结尾判断,则是通过判断是否到达了文件尾来确定的。
另外关于“底层都是用的字节流”这句,你其实弄反了,底层都是别的东西,字节流才是表象。ByteArrayInputStream 的底层是一个byte[],FileInputStream的底层是一个FileChannel。
再有就是这里不是包装模式,请不要混淆。
太感谢了,我明白了,谢谢。