java io SequenceInputStream源码分析

目录

简介

基础属性 e,in,构造函数2个,nextStream方法

available,两个read,close方法


简介

/**
 * SequenceInputStream表示其他inputstream的逻辑连接。
 * 它从一个有序的输入流集合开始,从第一个开始读取,直到到达文件末尾,
 * 然后从第二个开始读取,以此类推,直到到达所包含的最后一个输入流的文件末尾。
 *
 * @author  Author van Hoff
 * @since   JDK1.0
 */
public
class SequenceInputStream extends InputStream

基础属性 e,in,构造函数2个,nextStream方法

	
	// 内部的Enumeration,可以不断调用它的nextElement方法
    Enumeration<? extends InputStream> e;
    
    // 当前读取的输入流
    InputStream in;

    /**
     * 通过记住参数来初始化新创建的SequenceInputStream,
     * 该参数必须是一个Enumeration,生成对象的运行时类型为InputStream。
     * 枚举产生的输入流将被有序地读取,以提供要从这个SequenceInputStream读取的字节。
     * 在枚举的每个输入流被耗尽后,将通过调用其close方法关闭它。
     *
     * @param   e   an enumeration of input streams.
     * @see     java.util.Enumeration
     */
    public SequenceInputStream(Enumeration<? extends InputStream> e) {
        this.e = e;
        try {
        	// in为e的下一个流
            nextStream();
        } catch (IOException ex) {
            // This should never happen
            throw new Error("panic");
        }
    }

    /**
     * 通过记住两个参数(首先是s1,然后是s2)
     * 来初始化一个新创建的SequenceInputStream,
     * 以提供要从这个SequenceInputStream读取的字节。
     *
     * @param   s1   the first input stream to read.
     * @param   s2   the second input stream to read.
     */
    public SequenceInputStream(InputStream s1, InputStream s2) {
        Vector<InputStream> v = new Vector<>(2);

        v.addElement(s1);
        v.addElement(s2);
        e = v.elements();
        // 创建一个e给它
        try {
            nextStream();
        } catch (IOException ex) {
            // This should never happen
            throw new Error("panic");
        }
    }

    /**
     *  如果到达EOF,则继续在下一个流中读取。
     */
    final void nextStream() throws IOException {
    	// 如果当前的流不为null,关闭当前的流
        if (in != null) {
            in.close();
        }
        
        // in变成e的下一个元素,如果没有,为null
        if (e.hasMoreElements()) {
            in = (InputStream) e.nextElement();
            if (in == null)
                throw new NullPointerException();
        }
        else in = null;

    }

available,两个read,close方法

    /**
     * 返回可以从当前依赖的输入流读取(或跳过)的字节数的估计数,
     * 而不会被当前依赖的输入流的方法的下一次调用阻塞。
     * 下一个调用可能是同一个线程或另一个线程。
     * 单个读取或跳过这许多字节不会阻塞,但可能读取或跳过更少的字节。
     * 此方法只是调用当前依赖的输入流的available方法并返回结果。
     *
     * @return an estimate of the number of bytes that can be read (or
     *         skipped over) from the current underlying input stream
     *         without blocking or {@code 0} if this input stream
     *         has been closed by invoking its {@link #close()} method
     * @exception  IOException  if an I/O error occurs.
     *
     * @since   JDK1.1
     */
    public int available() throws IOException {
        if (in == null) {
            return 0; // no way to signal EOF from available()
        }
        return in.available();
    }

    /**
     * 从这个输入流中读取下一个字节的数据。
     * 字节作为0到255之间的int类型返回。
     * 如果由于到达流的末尾而没有可用的字节,则返回-1值。
     * 此方法将一直阻塞,直到输入数据可用、检测到流的末尾或抛出异常为止。
     * <p>
     * 该方法尝试从当前子流中读取一个字符。
     * 如果它到达流的末尾,它将调用当前子流的close方法并开始从下一个子流读取。
     *
     * @return     the next byte of data, or <code>-1</code> if the end of the
     *             stream is reached.
     * @exception  IOException  if an I/O error occurs.
     */
    public int read() throws IOException {
        while (in != null) {
            int c = in.read();
            if (c != -1) {
                return c;
            }
            nextStream();
        }
        // 不会返回-1,知道所有流都被读完
        return -1;
    }

    /**
     * 从这个输入中读取最多len字节的数据流到一个字节数组。
     * 如果len不为零,该方法将阻塞,直到至少有1个字节的输入可用;
     * 否则,什么字节都不读取并返回0。
     * <p>
     * SequenceInputStream的read方法尝试从当前子流中读取数据。
     * 如果由于子流已经到达流的末尾而无法读取任何字符,
     * 则调用当前子流的close方法,并从下一个子流开始读取。
     *
     * @param      b     the buffer into which the data is read.
     * @param      off   the start offset in array <code>b</code>
     *                   at which the data is written.
     * @param      len   the maximum number of bytes read.
     * @return     int   the number of bytes read.
     * @exception  NullPointerException If <code>b</code> is <code>null</code>.
     * @exception  IndexOutOfBoundsException If <code>off</code> is negative,
     * <code>len</code> is negative, or <code>len</code> is greater than
     * <code>b.length - off</code>
     * @exception  IOException  if an I/O error occurs.
     */
    public int read(byte b[], int off, int len) throws IOException {
        if (in == null) {
            return -1;
        } else 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;
        }
        do {
        	// 从当前的in读取,如果为0,则下一个流
            int n = in.read(b, off, len);
            if (n > 0) {
                return n;
            }
            nextStream();
        } while (in != null);
        return -1;
    }

    /**
     * 关闭该输入流并释放与该流关联的任何系统资源。
     * 已关闭的SequenceInputStream不能执行输入操作,也不能重新打开。
     * <p>
     * 如果该流是从enumeration创建的,
     * 则从枚举请求所有剩余的元素,并在close方法返回之前关闭。
     *
     * @exception  IOException  if an I/O error occurs.
     */
    public void close() throws IOException {
        do {
        	// 不断关闭当前流,并下一个
            nextStream();
        } while (in != null);
    }

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值