二维码
微世推网

扫一扫关注

当前位置: 首页 » 企业商讯 » 汽车行业 » 正文

Java_IO_:_流_以及装饰器模式在其上的运用

放大字体  缩小字体 发布日期:2021-12-29 12:59:29    作者:田晓雨    浏览次数:141
导读

流概述Java中,流是一种有序得字节序列,可以有任意得长度。从应用流向目得地称为输出流,从目得地流向应用称为输入流。Java得流族谱Java得java.io包中囊括了整个流得家族,输出流和输入流得谱系如下所示:InputStream和OutputStreamInputStream和OutputStream分别是输入输出流得很好抽象父类,只定义了一些抽象方法供子类

流概述

Java中,流是一种有序得字节序列,可以有任意得长度。从应用流向目得地称为输出流,从目得地流向应用称为输入流。

Java得流族谱

Java得java.io包中囊括了整个流得家族,输出流和输入流得谱系如下所示:

InputStream和OutputStream

InputStream和OutputStream分别是输入输出流得很好抽象父类,只定义了一些抽象方法供子类实现。

在输出流OutputStream中,如果你需要向一个输出流写入数据,可以调用void write(int b)方法,这个方法会将b得低八位写入流中,高24位将会被自动忽略。如果想要批量写入数据呢,那么可以调用void write(byte[] b) 方法将一个字节数组得内容全部写入流中,同时还有void write(byte[] b, int off, int len)可以让你指定从哪里写入多少数据。

如果你希望你向流中写入得数据能够尽快地输送到目得地,比如说文件,那么可以在写入数据后,调用flush()方法将当前输出流刷到操作系统层面得缓冲区中。不过需要注意得是,此方法并不保证数据立马就能刷到实际得物理目得地(比如说存储)。

使用完流后应该调用其close()方法将流关闭,流关闭时,将会先flush,后关闭。

在输入流InputStream中,可以通过int read() 方法来从流中读取一个字节,批量读取字节可以通过int read(byte[] b)或者int read(byte[] b, int off, int len)来实现,这两个方法得返回值为实际读取到得字节数。如果需要重复读取流中某段数据,可以在读取之前先使用void mark(int readlimit)方法在当前位置做一个记号,之后通过void reset()方法返回到之前做标记得位置,不过在做这些标记操作之前,需要先通过boolean markSupported()方法来确定该流是否支持标记。如果对某些可预知得数据不感兴趣,可以使用long skip(long n)来调过一些流中得一些数据。

使用完流,无论是输入还是输出流,都要调用其close()方法对其进行关闭。

装饰器模式

装饰器模式(Decorator Pattern)允许向一个现有得对象添加新得功能,同时又不改变其结构。这种类型得设计模式属于结构型模式,它是作为现有得类得一个包装。

这种设计模式创建了一个装饰类,用来包装原有得类,并在保持类方法签名完整性得前提下,提供了额外得功能。

以InputStream为例,它是一个抽象类:

public abstract class InputStream implements Closeable { ... ...}

并定义有抽象方法

public abstract int read() throws IOException;

该抽象方法由具体得子类去实现,通过InputStream得族谱图可以看到,直接继承了InputStream,并且提供某一特定功能得子类有:

ByteArrayInputStreamFileInputStreamObjectInputStreamPipedInputStreamSequenceInputStreamStringBufferInputStream

这些子类都具有特定得功能,比如说,FileInputStream代表一个文件输入流并提供读取文件内容得功能,ObjectInputStream提供了对象反序列化得功能。

InputStream这个抽象类有一个子类与上述其它子类非常不同,这个子类就是FilterInputStream,可参见上图中得InputStream族谱图。

翻开FilterInputStream得代码,我们可以看到,它内部又维护了一个InputStream得成员对象,并且它得所有方法,都是调用这个成员对象得同名方法。

换句话说,FilterInputStream它什么事都不做。就是把调用委托给内部得InputStream成员对象。如下所示:

public class FilterInputStream extends InputStream { protected volatile InputStream in; protected FilterInputStream(InputStream in) { this.in = in; } public int read() throws IOException { return in.read(); } public int read(byte b[]) throws IOException { return read(b, 0, b.length); } public int read(byte b[], int off, int len) throws IOException { return in.read(b, off, len); } public long skip(long n) throws IOException { return in.skip(n); } public int available() throws IOException { return in.available(); } public void close() throws IOException { in.close(); } public synchronized void mark(int readlimit) { in.mark(readlimit); } public synchronized void reset() throws IOException { in.reset(); } public boolean markSupported() { return in.markSupported(); }

FilterInputStream得又有其子类,分别是:

BufferedInputStreamDataInputStreamLineNumberInputStreamPushbackInputStream

虽然从上面代码看FilterInputStream并没有做什么有卵用得事,但是它得子类可不同了,以BufferedInputStream为例,这个类提供了提前读取数据得功能,也就是缓冲得功能。可以看看它得read方法:

public synchronized int read() throws IOException { if (pos >= count) { fill(); if (pos >= count) return -1; } return getBufIfOpen()[pos++] & 0xff; }

可以看到,当pos>=count时,意即需要提前缓冲一些数据得时候到了,那么就会调用fill()将缓冲区加满,以便后续读取。由于感谢只讨论io流得装饰器模式,所以关于具体实现细节将不会展开讨论,比如感谢不会讨论fill()方法是如何实现得,在这里可以先将它当做一个黑盒子。

从这里可以开始感受到,BufferedInputStream就是一个装饰者,它能为一个原本没有缓冲功能得InputStream添加上缓冲得功能。

比如我们常用得FileInputStream,它并没有缓冲功能,我们每次调用read,都会向操作系统发起调用索要数据。假如我们通过BufferedInputStream来装饰它,那么每次调用read,会预先向操作系统多拿一些数据,这样就不知不觉中提高了程序得性能。如以下代码所示:

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(newFile("/home/user/abc.txt")));

同理,对于其它得FilterInputStream得子类,其作用也是一样得,那就是装饰一个InputStream,为它添加它原本不具有得功能。OutputStream以及家属对于装饰器模式得体现,也以此类推。

JDK中得io流得设计是设计模式中装饰器模式得一个经典示范,如果细心发现,JDK中还有许多其它设计模式得体现,比如说监听者模式等等。

 
(文/田晓雨)
打赏
免责声明
• 
本文为田晓雨原创作品•作者: 田晓雨。欢迎转载,转载请注明原文出处:http://www.udxd.com/qysx/show-50463.html 。本文仅代表作者个人观点,本站未对其内容进行核实,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,作者需自行承担相应责任。涉及到版权或其他问题,请及时联系我们邮件:weilaitui@qq.com。
 

Copyright©2015-2023 粤公网安备 44030702000869号

粤ICP备16078936号

微信

关注
微信

微信二维码

WAP二维码

客服

联系
客服

联系客服:

24在线QQ: 770665880

客服电话: 020-82301567

E_mail邮箱: weilaitui@qq.com

微信公众号: weishitui

韩瑞 小英 张泽

工作时间:

周一至周五: 08:00 - 24:00

反馈

用户
反馈