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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值