黑马程序员技术交流社区

标题: read和write的区别,求解析 [打印本页]

作者: 陈志强    时间: 2013-3-21 12:56
标题: read和write的区别,求解析
本帖最后由 陈志强 于 2013-3-21 17:22 编辑

刚刚看到视频IO流的部分,在自定义字节流缓冲区是如何保证拷贝的数据没有变化的呢?

InputStream中的read()方法和BufferedOutputStream中的write()方法有什么区别呢?它们是怎么样保证原数据不变化呢?
为什么read方法返回不是byte类型而是int类型的呢?
还望大神解答一下,谢谢!
作者: blackcaismine    时间: 2013-3-21 13:17
本帖最后由 blackcaismine 于 2013-3-21 13:21 编辑

InputStream中的read()方法从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
read()也可以读数组形式的byte[]
而BufferedOutputStream中的write()方法是将指定的字节或者byte 数组写入此缓冲的输出流,


作者: 抽烟男孩    时间: 2013-3-21 13:21
鄙人浅析InputStream为字节流故read()方法返回值为byte型,InputStream与BufferedOutputStream两个类的区别主要是后者在继承前者的基础上多了些包装,相对于前者读写速度更快。另外后者如果IO流不及时Flush并关闭的话后果相当严重{:soso_e107:}
作者: 小路飞    时间: 2013-3-21 13:21
本帖最后由 侯国奇 于 2013-3-21 14:30 编辑

  因为有可能会读到连续8个二进制1(对应的十进制是-1)的情况,那么就会存在数据还没有读完,就已经结束的情况。因为我们判断文件是否读取结束也是通过结尾标记-1来确定的。所以,为了避免这种情况将读到的字节byte进行int类型的提升,并在保留原字节数据的情况前面了补了24个0,变成了int类型的数值。
而在写入数据,即write时,则又进行了强转操作,只写入了该int类型数据的最低8位。

作者: 王龙涛    时间: 2013-3-21 14:53
lz下面是我在网上找的,虽然我也不太明白但我只能帮到你这了

InputStream()中的read方法

public abstract int read()throws IOException

从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。
如果因为已经到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、
检测到流末尾或者抛出异常前,此方法一直阻塞。子类必须提供此方法的一个实现。

返回:
下一个数据字节;如果到达流的末尾,则返回 -1。

抛出:
IOException - 如果发生 I/O 错误。
问题一:为啥读取的是一个byte,返回值是int,为什么这么麻烦?如果从输入流中读取的下一个字节是11111111(十进制为-1),(ch = in.read()) != -1为false,输出流中读入不就中止了吗?

read()方法返回的是“ 0 到 255 范围内的 int 字节值”,问题一的实质变为了:读取时遇到11111111返回的是什么?

查看此例中read()方法的源码(java.io.BufferedInputStream):

public synchronized int read() throws IOException {
    if (pos >= count) {
        fill();
        if (pos >= count)
            return -1;
        }
        return getBufIfOpen()[pos++] & 0xff;
    }
可以看出,read()返回的是和0xff与运算的结果。

-1和0xff与运算:

11111111 11111111 11111111 11111111
&00000000 00000000 00000000 11111111
------------------------------------
00000000 00000000 00000000 11111111
结果变为了255,确实不是-1。byte范围是-128到127,"和0xff与运算"这样的处理,将返回值的范围变为了0到255方法了,
这样就可以将“-1”作为读取到流末尾的返回值了。

问题一得到了解决,那么,既然读取的是一个int,写入的时候时候怎么办。

查看此例中的write(int)方法(java.in.BufferedOutputStream):

public synchronized void write(int b) throws IOException {
        if (count >= buf.length) {
            flushBuffer();
        }
        buf[count++] = (byte)b;
    }
可以看出,如果读取的是11111111,返回的是255,写入的时候将255转换为byte即-1。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2