ImputStream源码学习

一.概述

是所有字节输入流的超类

二.源码


// jdk7

package java.io;

/**
 * 字节输入流的所有类的超类
 * @since   JDK1.0
 */
public abstract class InputStream implements Closeable {
	// 用于确定skip时要使用的最大缓冲区大小。
    private static final int MAX_SKIP_BUFFER_SIZE = 2048;

    /**
	 * 从输入流中读取数据的下一个字节。
	 * 在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
     *
     * @return 返回下一个字节数据,为0到255范围内的int值
	 *         如果已经到达流末尾而没有可用的字节,则返回值 -1。
     * @exception  IOException  if an I/O error occurs.
     */
    public abstract int read() throws IOException;

    /**
	 * 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中
     * 相当于read(b, 0, b.length)
     * @param      b   存储读入数据的缓冲区
     * @return     读入缓冲区的总字节数;如果因为已经到达流末尾而不再有数据可用,则返回 -1。
     */
    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

    /**
     * 将输入流中最多 len 个数据字节读入 byte 数组。
	 * 尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。
     *
     * @param      b     读入数据的缓冲区
     * @param      off   数据写入缓冲区b[]中的开始下标off
     * @param      len   要读取的最大字节数.
     * @return     读入缓冲区的总字节数;如果因为已到达流末尾而不再有数据可用,则返回 -1。
     */
    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;
    }

    /**
	 * 跳过和丢弃此输入流中数据的 n 个字节。
	 * 出于各种原因,skip 方法结束时跳过的字节数可能小于该数,也可能为 0
     *
     * @param      n   要跳过的字节数
     * @return     跳过的实际字节数
     */
    public long skip(long n) throws IOException {
		// 需要跳过的字节数
        long remaining = n;
        int nr;
        if (n <= 0) {
            return 0;
        }
        int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
        byte[] skipBuffer = new byte[size];
        while (remaining > 0) {
			// 实际字节数
            nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
            if (nr < 0) {
                break;
            }
            remaining -= nr;
        }
        return n - remaining;
    }

    /**
	 * 返回可以不受阻塞地从此输入流读取(或跳过)的估计字节数;如果到达输入流末尾,则返回 0。
	 * 如上传本地文件,通过FileINputStream读取返回文件具体大小
     */
    public int available() throws IOException {
        return 0;
    }

    /**
	 * 关闭此输入流并释放与该流关联的所有系统资源
	 * InputStream 的 close 方法不执行任何操作

     */
    public void close() throws IOException {}

    /**
	 * 在此输入流中标记当前的位置
	 *
	 * mark 的常规协定是:如果方法 markSupported 返回 true,那么输入流总是在调用 mark 之后记录所有读取的字节,
	 *                    并时刻准备在调用方法 reset 时(无论何时),再次提供这些相同的字节。
	 *                    但是,如果在调用 reset 之前从流中读取多于 readlimit 的字节,则不需要该流记录任何数据。 
	 *
	 * mark就像书签一样,用于标记,以后再调用reset时就可以再回到这个mark过的地方。
	 * mark方法有个参数readlimit,通过这个整型参数,你告诉系统,希望在读出这么多个字符之前,这个mark保持有效。
	 * 比如说mark(10),那么在read()读取10个以内的字符时,reset()操作后可以重新读取已经读出的数据,
	 * 如果已经读取的数据超过10个,那reset()操作后,就不能正确读取以前的数据了,因为此时mark标记已经失效。 
	 *
	 * InputStream 的 mark 方法不执行任何操作。
     *
     * @param   readlimit   在标记位置失效前可以读取字节的最大限制
     */
    public synchronized void mark(int readlimit) {}

    /**
	 * 将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。 
	 * reset 的常规协定是: 
	 *	如果方法 markSupported 返回 true,那么: 
	 *		如果创建流以后未调用方法 mark,或最后调用 mark 以后从该流读取的字节数大于最后调用 mark 时的参数,则可能抛出 IOException。 
	 *		如果未抛出这样的 IOException,则将该流重新设置为这种状态:最近一次调用 mark 以后(如果未调用过 mark,则从文件开头开始)读取的所有字节将重新提供给 read 方法的后续调用者,后跟任何从调用 reset 时起将作为下一输入数据的字节。 
	 *	如果方法 markSupported 返回 false,那么: 
	 *		对 reset 的调用可能抛出 IOException。 
	 *		如果未抛出 IOException,则将该流重新设置为一种固定状态,该状态取决于输入流的特定类型及其创建方式。提供给 read 方法后续调用者的字节取决于特定类型的输入流。 
	 *	除了抛出 IOException 之外,类 InputStream 的方法 reset 不执行任何操作。 
	 *
     */
    public synchronized void reset() throws IOException {
        throw new IOException("mark/reset not supported");
    }

    /**
     * 测试此输入流是否支持 mark 和 reset 方法。
	 * 是否支持 mark 和 reset 是特定输入流实例的不变属性。
	 * InputStream 的 markSupported 方法返回 false。 
     */
    public boolean markSupported() {
        return false;
    }

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值