java IO笔记(SequenceInputStream)

本篇讲的java io中的SequenceInputStream流。

SequenceInputStream是一个合并流,当我们从多个流中读取数据,并希望他们合并成一个流作为数据源时,我们就可以使用SequenceInputStream。它的内部是通过Vector来实现的,至于Vector是什么会在其他的篇幅中提到,这里暂且就把它看做一个普通的集合。

下面先贴上SequenceInputStream的源码:

 

package java.io;

import java.io.InputStream;
import java.util.Enumeration;
import java.util.Vector;

public class SequenceInputStream extends InputStream {

    //Enumeration是一个枚举接口,这里声明了一个该类型的变量
    Enumeration e;
    //封装了一个InputStream in
    InputStream in;

    /**
    *带有一个参数的构造方法,传入一个Enumeration的对象。
    */
    public SequenceInputStream(Enumeration e) {
        //将传入的参数赋值给本地的e。
        this.e = e;
        try {
	    //执行nextStream方法,如果本地Enumeration对象中包含InputStream流,则将其中的第一个流赋值给本地声明的InputStream对象in。
            nextStream();
        } catch (IOException ex) {
            // This should never happen
            throw new Error("panic");
        }
    }

    /**
    *带两个参数的构造方法,两个参数都为InputStream流对象
    */
    public SequenceInputStream(InputStream s1, InputStream s2) {
        //定义了一个Vector对象,容量为2
        Vector v = new Vector<>(2);
        //将传入的两个参数传入Vector中。
        v.addElement(s1);
        v.addElement(s2);
        //通过Vector的elements方法获得Enumeration对象,并赋值给本地声明的Enumeration对象e。
        e = v.elements();
        try {
            //执行nextStream方法,如果本地Enumeration对象中包含InputStream流,则将其中的第一个流赋值给本地声明的InputStream对象in。
            nextStream();
        } catch (IOException ex) {
    /        // This should never happen
            throw new Error("panic");
        }
    }

    /**
    *给方法用于为本地声明的InputStream对象in赋值
    */
    final void nextStream() throws IOException {
	//如果in已经被创建过,那么先断开连接
        if (in != null) {
            in.close();
        }

	//遍历本地的Enumercation对象,如果其中含有元素,将其中的元素赋值给本地的InputStream对象in,每一赋值是赋值的e中的下一个元素,从
        //第一个元素开始(下标为0)。
        if (e.hasMoreElements()) {
            in = (InputStream) e.nextElement();
            if (in == null)
                throw new NullPointerException();
        }
	//如果Enumercation对象中没有元素,则将本地InputStream对象in置为null
        else in = null;

    }

    /**
    *该方法用来判断流是否可读
    */
    public int available() throws IOException {
        if(in == null) {
            return 0; // no way to signal EOF from available()
        }
        return in.available();
    }

    /**
    *读取方法,按照字节读取,当当前流对象中读取完毕时,调用nextStream方法,换取下一个流继续进行数据读取,其中用了一次迭代方法。
    */
    public int read() throws IOException {
        if (in == null) {
            return -1;
        }
        int c = in.read();
        if (c == -1) {
            nextStream();
            return read();
        }
        return c;
    }

    
    /**
    *读取方法,按照传入的字节数组进行读取,当当前流对象中读取完毕时,调用nextStream方法,换取下一个流继续进行数据读取,其中用了一次迭
    *代方法。
    */
    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;
        }

        int n = in.read(b, off, len);
        if (n <= 0) {
            nextStream();
            return read(b, off, len);
        }
        return n;
    }

    /**
    *关闭所有的流对象
    */
    public void close() throws IOException {
        do {
            nextStream();
        } while (in != null);
    }
}

下面将举一个小例子来说明SequenceInputStream的使用方式:

 

 

package sequenceIO;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;


public class SequenceIOTest {
	public static void main(String[] args) {
		String str = "Hello World!";
		String str1 = "i am LiLei, how r u ,bro?";
		int len;
		StringBuffer message = new StringBuffer();
		InputStream is1 = new ByteArrayInputStream(str.getBytes());
		InputStream is2 = new ByteArrayInputStream(str1.getBytes());
		SequenceInputStream sis = new SequenceInputStream(is1, is2);
		
		try {
			while((len = sis.read()) != -1){
				message.append((char)len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				if(sis!=null){
					sis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println(message);
	}
}

执行上述代码可以在控制台看到如下打印:

 

由此可以看出,SequenceInputStream成功将两个流中的数据汇聚到了一起,以上为本篇内容。



 

转载于:https://www.cnblogs.com/moonfish1994/p/10222428.html

你可能感兴趣的:(java)