资讯专栏INFORMATION COLUMN

java.io (2) 输入流的复用

kun_jian / 2274人阅读

摘要:输入流的复用在实际的开发中是很常见的场景。根据对的抽象,流的复用是矛盾的。检查当前流类是否支持标记功能这三个方法能有效地解决流复用的问题。

输入流的复用在实际的开发中是很常见的场景。

在实际应用中,很多需要提供输入数据的API都是用IputStream类作为其参数类型,比如XML文档的解析API就是一个典型的例子。同时很多数据的提供者允许使用者通过InputStream类的对象方式来读取数据。

根据java对io的抽象(Stream),流的复用是矛盾的。按照流本身所代表的抽象含义,数据一旦流过去了,就无法被再次利用了。

对于现实应用中存在的对输入流的需求,基本上来说的两种方式可以解决;第一种是利用输入流提供的标记和重置的控制能力,第二种则是把输入流转换成数据来使用。

方法一, 缓冲流类标记与重置

好在java为我们提供现成的解决方案。
BufferedInputStream, BufferedOutputStream
利用这两个类中提供的

public synchronized void mark(int readlimit) 读取位置标记,需要一个允许读取的字节数。
public synchronized void reset() throws IOException 将读取位置重置到标记位置。
public boolean markSupported() 检查当前流类是否支持标记功能

这三个方法能有效地解决流复用的问题。

java   // 假如我们有三个方法,需要串行的使用我们的 io 输入流。
   // public static void process1(InputStream in) throws IOException;
   // public static void process2(InputStream in) throws IOException;
   // public static void process3(InputStream in) throws IOException;

   if (!input.markSupported()) {
       this.input = new BufferedInputStream(input);
   }
   else
   {
       this.input = input;
   }

   // 为了能够复用整个流
   this.input.mark(Integer.MAX_VALUE); 

   process1(this.input);
   // 重置读取位置,以供下一个使用者使用,以下雷同
   this.input.reset();

   process2(this.input);
   this.input.reset();

   process3(this.input);
   this.input.reset();
方法二, 将流转化成为数据流类

这一种方案就是将流中的数据全部读取到一个字节数组中。在不同的数据接收者之间这些数据的传递是通过字节数组完成的。
将 字节流转化成字节数组 可以使用我们 ByteArrayInputStreamByteArrayOutputStream。这样的话,我们传递的是数据,而不再是原始的io。


ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[2048]; for (int count=0; ( inputStream.read(buffer) ) != -1; ) { arrayOutputStream.write(buffer, 0, count); } ByteArrayInputStream byteArrayOutputStream = new ByteArrayInputStream(arrayOutputStream.toByteArray()); // byteArrayOutputStream 对象就可以作为我们需要复用的数据流,配合 `mark`和`reset` 功能提高io性能。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64225.html

相关文章

  • 初探Java Socket

    摘要:绑定完成后允许套接字进行连接并等待连接。服务端根据报文返回响应,并关闭连接。单线程服务器多进程及多线程服务器复用服务器复用的多线程服务器单线程服务器一次只处理一个请求,直到其完成为止。 前言 本篇文章将涉及以下内容: IO实现Java Socket通信 NIO实现Java Socket通信 阅读本文之前最好了解过: Java IO Java NIO Java Concurrenc...

    张汉庆 评论0 收藏0
  • 关于Java IO与NIO知识都在这里

    摘要:从通道进行数据写入创建一个缓冲区,填充数据,并要求通道写入数据。三之通道主要内容通道介绍通常来说中的所有都是从通道开始的。从中选择选择器维护注册过的通道的集合,并且这种注册关系都被封装在当中停止选择的方法方法和方法。 由于内容比较多,我下面放的一部分是我更新在我的微信公众号上的链接,微信排版比较好看,更加利于阅读。每一篇文章下面我都把文章的主要内容给列出来了,便于大家学习与回顾。 Ja...

    Riddler 评论0 收藏0
  • JAVA IO BIO NIO AIO

    摘要:三同步非阻塞式以块的方式处理数据面向缓存区的采用多路复用模式基于事件驱动是实现了的一个流行框架,的。阿里云分布式文件系统里用的就是。四异步非阻塞式基于事件驱动,不需要多路复用器对注册通道进行轮询,采用设计模式。 一、什么是IO IO 输入、输出 (read write accept)IO是面向流的 二、BIO BIO是同步阻塞式IO 服务端与客户端进行三次握手后一个链路建立一个线程面...

    freecode 评论0 收藏0
  • JAVA IO BIO NIO AIO

    摘要:三同步非阻塞式以块的方式处理数据面向缓存区的采用多路复用模式基于事件驱动是实现了的一个流行框架,的。阿里云分布式文件系统里用的就是。四异步非阻塞式基于事件驱动,不需要多路复用器对注册通道进行轮询,采用设计模式。 一、什么是IO IO 输入、输出 (read write accept)IO是面向流的 二、BIO BIO是同步阻塞式IO 服务端与客户端进行三次握手后一个链路建立一个线程面...

    sshe 评论0 收藏0
  • java.io (1) 基本输入输出流

    摘要:基本输入流输入流类中包含两类功能输入流的两大功能读取流中字节数据的功能是通过方法来完成。基本输出流与类相对应的类表示基本的输出流,用来把数据从程序输出到其他地方。 一堆废话(赶快跳过) 在我们的日常开发中 I/O 涉及到我们开发的方方面面,虽然早在 JDK1.5 就新增了 NIO的概念,但是 java.io 的使用以及技巧在我们的日常开发中还是占据很高的比重。 概念(不看也行) ...

    haobowd 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<