Java

Java IO笔记(SequenceInputStream)

2019-12-11  本文已影响0人  moonfish1994

(最近刚来到简书平台,以前在CSDN上写的一些东西,也在逐渐的移到这儿来,有些篇幅是很早的时候写下的,因此可能会看到一些内容杂乱的文章,对此深感抱歉,以下为正文)


正文

本篇讲的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<? extends InputStream> e;
   //封装了一个InputStream in
   InputStream in;

   /**
   *带有一个参数的构造方法,传入一个Enumeration的对象。
   */
   public SequenceInputStream(Enumeration<? extends InputStream> 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<InputStream> 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成功将两个流中的数据汇聚到了一起,以上为本篇全部内容。

上一篇下一篇

猜你喜欢

热点阅读