【Java基础知识】IO流--SequenceInputStream 合并流

来源:互联网 发布:淘宝延期付款在哪里 编辑:程序博客网 时间:2024/05/24 03:27

1. SequenceInputStream概述及应用场景

SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
应用场景:多个文件合并到一个文件的场景。

构造方法:

public SequenceInputStream(Enumeration<? extends InputStream> e):

通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。将按顺序读取由该枚举生成的输入流,以提供从SequenceInputStream 读取的字节。在用尽枚举中的每个输入流之后,将通过调用该流的 close() 方法将其关闭。

public SequenceInputStream(InputStream s1, InputStream s2):

住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。
区别:这两种构造方法的区别是封装Enumeration对象的工作放到代码外。最终归结于为在构造函数内Enumeration类型成员变量初始化。SequenceInputStream源码分析,合并流,把多个文件写到一个文件中去。

2. SequenceInputStream源码

public class SequenceInputStream extends InputStream {    Enumeration e;    InputStream in;    public SequenceInputStream(Enumeration<? extends InputStream> e) {        this.e = e;        try {            nextStream();        } catch (IOException ex) {                  throw new Error("panic");        }    }    public SequenceInputStream(InputStream s1, InputStream s2) {        Vector  v = new Vector(2);        v.addElement(s1);        v.addElement(s2);        e = v.elements();        try {            nextStream();        } catch (IOException ex) {            // This should never happen            throw new Error("panic");        }    }    final void nextStream() throws IOException {        if (in != null) {            in.close();        }        if (e.hasMoreElements()) {            in = (InputStream) e.nextElement();            if (in == null)                throw new NullPointerException();        }        else in = null;    }    public int read() throws IOException {        if (in == null) {            return -1;        }        int c = in.read();        if (c == -1) {            nextStream();            return read();        }        return c;    }    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 int available() throws IOException {        if(in == null) {            return 0; // no way to signal EOF from available()        }        return in.available();    }       public void close() throws IOException {        do {            nextStream();        } while (in != null);    }   }

3. 案例:使用SequenceInputStream合并文件

需求:把a.txt,b.txt,c.txt三个文件的内容复制到Copy.txt中 。a.txt+b.txt+c.txt – Copy.txt

public class SequenceInputStreamDemo2 {    public static void main(String[] args) throws IOException {        /*SequenceInputStream(Enumeration e)          Enumeration是Vector中的一个方法的返回值类型。          Enumeration<E> elements()         * */        Vector<InputStream> v = new Vector<InputStream>();        InputStream s1 = new FileInputStream("a.txt");        InputStream s2 = new FileInputStream("b.txt");        InputStream s3 = new FileInputStream("c.txt");        v.add(s1);        v.add(s2);        v.add(s3);        Enumeration<InputStream> en = v.elements();        SequenceInputStream sis = new SequenceInputStream(en);        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Copy.txt"));          byte[] bys = new byte[1024];        int len = 0;        while ((len = sis.read(bys)) != -1) {            bos.write(bys, 0, len);        }        bos.close();        sis.close();    }}
0 0