JDK1.8 InputStream类原码及分析

 package java.io;

 public abstract class InputStream implements Closeable {
 
     // 当使用skip方法时,最大的buffer size大小
     private static final int MAX_SKIP_BUFFER_SIZE = 2048;
 
     /** 抽象方法 子类实现 读取数据*/
     public abstract int read() throws IOException;
 
    /**
     * 传入字节数组 返回数组长度
     * 实际调用 根据数组、起始位置、待读取长度参数返回数组长度 起始位为0 长度为数组长度
     * 将读取到的数据放在 byte 数组中,该方法实际上调用read(byte b[], int off, int len)方法
    */
     public int read(byte b[]) throws IOException {
         return read(b, 0, b.length);
     }
 
    /**
     * 从第 off 位置读取<b>最多(实际可能小于)</b> len 长度字节的数据放到 byte 数组中,流是以 -1 来判断是否读取结束的;
     * 此方法会一直阻塞,直到输入数据可用、检测到stream结尾或引发异常为止。
     * @param b 待读取数组
     * @param off 起始读取位置
     * @param len 待读取长度
     */
     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) {//起始位小于0 或待读取长度小于0 或待读取长度大于数组长度-起始位 报错 索引越界
             throw new IndexOutOfBoundsException();
         } else if (len == 0) {//待读取长度为0 直接返回
             return 0;
         }
        
         int c = read();//读取当前位字节 读取成功将当前位+1 读取不到返回-1
         if (c == -1) {//当前位读取结果为-1 则直接返回
             return -1;
         }
         b[off] = (byte)c;//将当前位字节放入数组
 
         int i = 1;
         try {
             for (; i < len ; i++) {//根据待读取长度遍历
                 c = read();//读取当前位字节 读取成功将当前位+1 读取不到返回-1
                 if (c == -1) {//当前位读取结果为-1 推出循环
                     break;
                 }
                 b[off + i] = (byte)c;//将读取的字节存入数组中
             }
         } catch (IOException ee) {
         }
         return i;//返回读取的字节长度
     }
 
     /**
      * 跳过指定个数的字节不读取
      */
     public long skip(long n) throws IOException {
 
         long remaining = n;//将传入长度另存为待读取长度
         int nr;//创建暂存值
 
         if (n <= 0) {//如果传入长度小于或等于0 则直接返回
             return 0;
         }
 
         int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);//将待读取长度与最大流长度作比较 取小的作为待创建数组长度
         byte[] skipBuffer = new byte[size];//创建空数组 长度为待读取长度或最大skip长度
         while (remaining > 0) {//当待读取长度大于 则执行操作
             nr = read(skipBuffer, 0, (int)Math.min(size, remaining));//从0位置开始 每次读取size或待读取的长度(当待读取长度过长时,取skip最大可读取长度,分多次读取,直到待读取长度小于skip最大可读长度;当待读取长度小于skip最大可读长度时,直接取待读取长度,一次读完)
             if (nr < 0) {//如果读取后的结果小于0 说明该次未读取到 即已经完全读取了指定的长度
                 break;//退出读取
             }
             remaining -= nr;//若读取后结果大于等于0 则将读取的长度从剩余待读取长度中去除 进行下一次读取
         }
 
         return n - remaining;//返回传入长度减去待读取长度 此时待读取长度应该为0 即返回的是传入长度 该长度内的信息已存入skipBuffer数组中
     }
 
     /**
      * 返回可读的字节数量
      */
     public int available() throws IOException {
         return 0;
     }

     /**
      * 读取完,关闭流,释放资源
      */
     public void close() throws IOException {}

     /**
      * 标记读取位置,下次还可以从这里开始读取,使用前要看当前流是否支持,可以使用 markSupport() 方法判断
      */
     public synchronized void mark(int readlimit) {}
 
     /**
      * 重置读取位置为上次 mark 标记的位置
      */
     public synchronized void reset() throws IOException {
         throw new IOException("mark/reset not supported");
     }
 
     /**
      * 判断当前流是否支持标记流,和上面两个方法配套使用。默认是false,由子类方法重写
      */
     public boolean markSupported() {
         return false;
     }
 
 }
 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值