zoukankan      html  css  js  c++  java
  • java IO(二):FileInputStream

    内容来自https://blog.csdn.net/ai_bao_zi/article/details/81097898,仅供我个人学习记录使用。

    本文主要说说public int read(int r)throws IOException{}和public int read(byte[] r) throws IOException{}这两个方法。

    public int read(int r)throws IOException{}
    这个方法从 InputStream 对象读取指定字节的数据。返回为整数值。返回下一字节数据,如果已经到结尾则返回-1。

    public int read(byte[] r) throws IOException{}
    这个方法从输入流读取r.length长度的字节。返回读取的字节数。如果是文件结尾则返回-1。

    对于上面这个方法,疑问是明明读取的是字节数据,为何返回值是int类型,而对于下面这个方法,问题就比较复杂:一是如果文件的内容是12345.那么流中一共有5个字节,但是我们设定的字节数组长度为2.那么会读取几次?每次情况是怎么样的?二是如果流中一共有5个字节,但是我们设定的字节数组长度为10,那么读取几次?每次情况是怎么样的?

    先说上面第一个方法的问题:

      1、方法解释中的-1相当于是数据字典告诉调用者文件已到底,可以结束读取了,这里的-1是Int型

      2、那么当文件未到底时,我们读取的是字节,若返回byte类型,那么势必造成同一方法返回类型不同的情况这是不允许的

      3、我们读取的字节实际是由8位二进制组成,二进制文件不利于直观查看,可以转成常用的十进制进行展示,因此需要把读取的字节从二进制转成十进制整数,故返回int型

      4、 因此结合以上3点,保证返回类型一致以及直观查看的情况,因此该方法虽然读取的是字节但返回int型
    接着是第二个方法的两个问题,这个就要从read(byte[] r)这个方法的源码来解释了:

    public int read(byte b[]) throws IOException {
            return read(b, 0, b.length);
        }

    可以看到调用了read(b,0,b.length)这个方法,再跳转,就是:

    public int read(byte b[], int off, int len) throws IOException {
            if (b == null) {
                throw new NullPointerException();
            } else if (off < 0 || len < 0 || len > b.length - off) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return 0;
            }
    
            int c = read();
            if (c == -1) {
                return -1;
            }
            b[off] = (byte)c;
    
            int i = 1;
            try {
                for (; i < len ; i++) {
                    c = read();
                    if (c == -1) {
                        break;
                    }
                    b[off + i] = (byte)c;
                }
            } catch (IOException ee) {
            }
            return i;
        }

    可以看到其原理是先依次判断数组b是否为null,off,len是否合法(读取的字节数必须小于等于该字符数组的指定使用长度[off为该数组开始可用的下标,一般为0,代表整个数组都可用作read]),判断过后,开始读取字符,如果流中已没有可以读取的字符,那么会返回-1,于是该方法也会返回-1,否则便把读取到的字节放入b[off],然后依次往下读放,直到读到指定数量或流中没有字符可读,注意如果此时流中没有字符可读,也是返回i(读取到的字符数量),而不会返回-1,只有下一次再调用该方法时才会返回-1。

    所以对于上面那个问题的第一种情况,会先读取12,34,54(4还留着没有被变动),最后再执行一次read返回-1。对于第二种情况,由于读完5,下一次循环就会出现c==-1的情况,会直接返回i(5),然后下一次再进入该方法返回-1,所以数组中多余的5个位置会被浪费,只有前五个位置有数据(后五个位置都为0)。

    这里再放上转载源的两张图,便于理解:

    第一种情况

    第二种情况

  • 相关阅读:
    奶牛跑步2
    数据结构练习
    HighChats报表使用C#mvc导出本地图片
    选择论
    投票选举
    价值
    工作5年后总结的工作经验
    formValidator 不支持jquery1.9以上的解决办法
    随想29:没有最完美的制度,只有最适合的制度
    随想28:愿我成为一个高级黑
  • 原文地址:https://www.cnblogs.com/MYoda/p/11163821.html
Copyright © 2011-2022 走看看