走进源码之InputStream

InputStream方法摘要:

public abstract int read() throws IOException;

public int read(byte b[]) throws IOException

public int read(byte b[], int off, int len) throws IOException 

public long skip(long n) throws IOException

public int available() throws IOException

public void close() throws IOException 

public synchronized void mark(int readlimit) 

public boolean markSupported()

package java.io;

/**
 * This abstract class is the superclass of all classes representing
 * an input stream of bytes.
 * 这个抽象类是所有字节输入流类的超类。
 */
public abstract class InputStream implements Closeable {

    // 允许跳过的最大字节数
    private static final int MAX_SKIP_BUFFER_SIZE = 2048;

    /**
     * 从输入流中读取下一个字节。返回0到255的整数,读到流的结尾返回-1.
     * 为什么不直接返回读取的字节的byte类型?是为了防止读到全1的字节,11111111是-1与结束符-1冲突,
     * 如果直接返回byte可能会导致流提前结束 <见FileInputStream>
     *
     * 该方法是唯一抽象方法,子类必须实现该方法
     *
     * @return     下一个数据字节,如果到达流末尾返回-1
     * 	 下一个数据字节就是已经读取的这个字节,开始我理解成是下一个待读取的字节。
     * @exception  IOException  if an I/O error occurs.
     */
    public abstract int read() throws IOException;

    /**
     * 从输入流中读一些字节到缓冲数组中。返回实际读取的字节数。
     * 
     * 如果数组b的长度是0,不会读取字节,结果返回0.读到流结束返回-1.
     *
     * 这个方法和read(b, 0, b.length)有同样的效果。
     * 
     * @param      b   the buffer into which the data is read.
     * @return     实际读取字节数,或-1
     * @exception  IOException 
     * @exception  NullPointerException  if <code>b</code> is <code>null</code>.
     * @see        java.io.InputStream#read(byte[], int, int)
     */
    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

    /**
     * 就是简单的重复调用read()方法,   
     *
     * @param      b     缓冲数组
     * @param      off   要写入数据的数组开始位置 <code>b</code>
     * @param      len   要读取的最大字节数
     * @return     读到缓冲数组中的实际字节数,到流结尾返回-1
     * @exception  IOException 
     * @exception  NullPointerException If <code>b</code> is <code>null</code>.
     * @exception  IndexOutOfBoundsException off是复制,len是复制,或len大于b.length - off 
     * @see        java.io.InputStream#read()
     */
    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();
        //空文件,直接返回-1,退出
        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个字节
     * 就是简单的重复调用read()方法,把n个字节保存在skipBuffer数组中,不返回给程序。
     *
     * @param      n   跳过字节数
     * @return     实际跳过的字节数
     * @exception  IOException  if the stream does not support seek,
     *                          or if some other I/O error occurs.
     */
    public long skip(long n) throws IOException {
 
        long remaining = n;
        int nr;

        if (n <= 0) {
            return 0;
        }
        //当跳过的字节数大于MAX_SKIP_BUFFER_SIZE时,就跳过MAX_SKIP_BUFFER_SIZE字节数。
        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;
    }

    /**
     
     * 返回估计可以读的字节数,怎么估计的??
     * 只是个估计值,不应该用这个返回值去定义缓冲数组的大小
     * 子类应该重写这个方法
     *
     * @return     an estimate of the number of bytes that can be read (or skipped
     *             over) from this input stream without blocking or 0 when
     *             it reaches the end of the input stream.
     * @exception  IOException if an I/O error occurs.
     */
    public int available() throws IOException {
        return 0;
    }

    /**
     * Closes this input stream and releases any system resources associated
     * with the stream.
     * 关闭输入流,释放所有占用的系统资源
     * InputStream中没有具体实现
     *
     * @exception  IOException  if an I/O error occurs.
     */
    public void close() throws IOException {}

    /**
     * 与reset()方法一起使用,可以实现重复利用InputStream中的指定一段数据
     *
     * @param   readlimit   the maximum limit of bytes that can be read before
     *                      the mark position becomes invalid.
     * @see     java.io.InputStream#reset()
     */
    public synchronized void mark(int readlimit) {}

    public synchronized void reset() throws IOException {
        throw new IOException("mark/reset not supported");
    }

    /**
     * 测试输入流是否支持mark(),reset()功能,默认不支持
     * @return  true if this stream instance supports the mark
     *          and reset methods; <code>false</code> otherwise.
     * @see     java.io.InputStream#mark(int)
     * @see     java.io.InputStream#reset()
     */
    public boolean markSupported() {
        return false;
    }

}


直接已知子类(链接至源码分析): 

 AudioInputStream, 

ByteArrayInputStream

FileInputStream, 

FilterInputStream,

ObjectInputStream, 

PipedInputStream,

SequenceInputStream, 

StringBufferInputStream

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值