内容发布更新时间 : 2024/11/15 10:31:41星期一 下面是文章的全部内容请认真阅读。
本文由我司收集整编,推荐下载,如有疑问,请与我司联系
Java 中 InputStream 装饰器模式的大家族
2018/02/26 0 你好!欢迎阅读我的博文,你可以跳转到我的个人博客网站,会 有更好的排版效果和功能。 此外,本篇博文为本人 Pushy 原创,如需转载请注明出 处:https://pushy.site/posts/1519819757
本文写在 po 主初学 JAVA 时,在学习 inputStream 摸不着头脑,受 Java IO-
InputStream 家族 -装饰者模式一文启发,因此在理清思路时写下本文。因为初学, 如有错误,望指正。
因为和输入流与之对应的还有输出流(即 OutputStream),在此只针对输入流
InputStream 讨论。
1. 家族老大: 一说起家族中的老大,InputStream 自然是当仁不让,在 java 的输 入流操作的类中,衍生出的基本子类有,可以理解为这些都是 InputStream 它的孩子 (子类):
InputStream 作为所有输入流中的超类,包含从输入流读取数据的基本方法,所有 的具体类都包含了这些方法,例如 read()方法,它将读取一个字节并将其以 int 类型 返回,当到达输入流的结尾时,返回-1,因此我们常常这样操作:
byte data;while ((data = (byte) bis.read()) != -1) { // 当没有达到输入流的结尾时, 继续读取并打印转换成 char 类型的字符: System.out.print((char) data);}这段代码不 了解不要紧,现在我们开始正式介绍 InputStream 家族。
2. 家族孩子: 家族中的子类各司其职,老大 FileInputStream 处理文件流,老二 ByteArrayInputStream 处理字节数组流... 例如,我们来看下老大是怎么工作的:
import java.io.*;import java.util.Date;public class FileInputStreamTest { public static void main(String[] args) throws Exception{ try { // 创建 FileInputStream 对象: FileInputStream fis = new FileInputStream(“E:\\\\text.txt”); // 得到起始时间: long start = System.currentTimeMillis( ); byte byteData; while ((byteData = (byte) bis.read()) != -1)
本文由我司收集整编,推荐下载,如有疑问,请与我司联系
{ System.out.print((char) byteData); // 得到读取后的结束时间: long end = System.currentTimeMillis( ); // 计算出读取的时间: long diff = end - start; System.out.println(“读取的时间时间共:” + diff); fis.close(); } catch (Exception e) { e.printStackTrace();}工作完成后,我们可以得到老大干完活的花费的时间为:1097, 但是家族老大嫌这家伙干活太慢了。老大无奈,叫来了它的弟弟老二
BufferedInputStream,俗话说啊,兄弟齐心,其利断金。果不其然,兄弟俩一块干活 效率果然加快了不少:
在如下的代码中我们可以看到,通过将 FileInputStream 放到 BufferedInputStream 中的构造方法中去创建 BufferedInputStream 对象,这样 FileInputStream 也就具有了 缓存的输入流功能。
public class BufInputStream { public static void main(String[] args) throws
Exception{ try { // 通过缓冲区数据向输入流添加功能,维护一个内部缓冲区以存储 从底层输入流读取的字节: BufferedInputStream bis = new BufferedInputStream(new FileInputStream(“E:\\\\text.txt”)); long start = System.currentTimeMillis( ); byte byteData; while ((byteData = (byte) fis.read()) != -1) { System.out.print((char) byteData); long end = System.currentTimeMillis( ); long diff = end - start; System.out.println(“读取的时间时间 共:” + diff); bis.close(); } catch (Exception e) { e.printStackTrace();}现在我们来看下兄 弟俩一块工作花费的时间吧:281。嘿!果然快了不少!看来增加缓冲流的功能的效 果的确十分明显。
这下老二在家族的名声增大了不少,许多的兄弟都找他搭档干活了。
3. 总结: 通过上文的假设,我们可以明白了在 io-InputStream 的家族中,采用 了装饰者的设计模式,即不改变原类文件和使用继承的前提下,动态地扩展一个对 象的功能(比如说这里的支持缓冲流),通过创建一个包装对象(这里的 BufferedInputStream),也就是装饰包裹真实的对象。
例如我们还可以也 ByteArrayInputStream 中修饰 PushbackInputStream 类:
本文由我司收集整编,推荐下载,如有疑问,请与我司联系
PushbackInputStream pbi = new PushbackInputStream (new
ByteArrayInputStream(b));ByteArrayInputStream 是处理字节数组流;
PushbackInputStream 是向输入流中添加功能,允许使用 unread()方法推回读取的字 节。这样我们就可以使用 pbi 对象处理字节数组,还具有推回读取字节的功能了:
import java.io.*;public class BAStreamAndPBStream { public static void
main(String[] args) throws IOException{ byte[] b = {1,2,3}; PushbackInputStream pbi = new PushbackInputStream (new ByteArrayInputStream(b)); int result; while ((result = pbi.read()) != -1) { System.out.print(result + “ “); pbi.unread(result); pbi.read(); System.out.print(result + “ “); pbi.close();// 运行结果为:// 1 1 2 2 3 3 好了,有关 InputStream 的大家族到这里介绍完了!如果你还有不明白的,可以阅读一下文章 Java IO-InputStream 家族 -装饰者模式。
tips:感谢大家的阅读,本文由我司收集整编。仅供参阅!