转自:http://hzxdark.iteye.com/blog/40133

hzxdark的博客

我不知道各位是师弟师妹们学java时是怎样的,就我的刚学java时的感觉,java.io包是最让我感到一头雾水的。所以现在这篇文,尽可能简单地描述java.io包的结构,希望对java.io同样一头雾水的师弟师妹们有些帮助^_^

我开始学java时,java.io的介绍是在《java编程思想》里看的。说实话,当时完全看不明白——“java.io的是用‘decorator模式’来构建的”——刚学java时,天知道啥玩意叫decorator……

不过要明白java.io,确实需要理解decorator设计模式,下面详细介绍下。
所谓decorator,装饰,其实可以说是一种设计的技巧,说白了没什么难的,别看很多网上资料说的天花乱坠的(非常讨厌有些文章总是把简单的问题描述得跟两头猪的kiss问题一样复杂……)。

decorator的结构如下:

MyInterface
       |
_______|_______
|             | 
Myclass     Decorator
          ____|_____
          |        | 
  DecoratorA      DecoratorB

decorator的目的是在不改变任何原有的类的基础下,添加新的功能(你可以理解为书上说的灵活性)。其中Myclass是你要扩展的类,DecoratorA跟DecoratorB封装了你要扩展的功能,并保存有一个MyInterface的引用。

考虑以下代码:
public static void main(Strings[] arg){
  myInterface a = new myClass();
  a.print();
}
myInterface 是myClass的接口,只声明了一个方法print(),myClass实现了该方法:

public void print(){
   System.out.println("hello");
}

那么假如我们要在不改变原来的myClass的基础上,变成输出“hello world!”,要怎么做呢?
当然我们可以考虑直接写个myClass的子类,helloClass之类,但是要是要求根据环境不同,输出"hello world!",my hello world","my Hello"之类的组合呢?
用继承的方式将不得不写一堆类似的子类来。

decorator,装饰模式的解决方法是,只实现基本的功能,把附加的功能抽出来放一边。
例如以下代码:
class DecoratorA implements Decorator{
   MyInterface myObject;
   DecoratorA(myInterface myObject){
     this.myObject = myObject; 
   }
   public void print(){
         myObject.print();
         System.out.print("world!");
   }
}

class DecoratorB implements Decorator{
    MyInterface myObject;
    DecoratorA(myInterface myObject){
     this.myObject = myObject; 
    }
    public void print(){
         System.out.print("my");
         myObject.print();
    }
}

DecoratorA和DecoratorB的功能分别是打印出world跟my。这时main函数要打印出my hello world可简单变为:

public static void main(Strings[] arg){
  MyInterface a =new DecoratorA(new DecoratorB(new MyClass());
  a.print();
}

简单吧?简单的说,就是:
print(){
  print("xxx");//可替换成你要添加的任何处理;
  myObject.print();//调用基础类的函数;
  xxxx;        //后续处理
}
Decorator的介绍就到此为止,接下来讲java.io.

看到

MyInterface a =new DecoratorA(new DecoratorB(new MyClass());

是不是觉得眼熟咧?这跟

BufferedInputStream bis = new BufferedInputStream(new DataInpuStream(new FileInputStream("xxx.txt")));

是不是很像?

(画外音加一个臭鸡蛋扔上来:因为java.io就是用decorator模式组织的,当然像啦……)

java.io分Stream跟reader、writer两大类,这里只详细介绍Stream,并最后两者间的关系。Stream又分inputStream、OutputStream,两者基本是对称的,这里也只介绍InputStream.

java.io.InputStream
                        |
 _______________________|________________________
 |                                             |
ByteArrayInputStream                      FilterInputStream
StringBufferInputStream   _____________________|____________________________
FileInputStream           |                |                    |          |
PipedInputStream  DataInputStream BufferedInputStream  LineNumInpuStream XXX

(注:xxx是PushbackInputStream,上面的图放不下)

这个图跟最初介绍的hello world的图很像吧?呵呵。
基础的流只有左边4个,这些流代表了数据的来源,所有的流都必须从这四个中之一开始。(注,还有一个RandomAccessFile、File,这两个不在本文介绍范围)。
然后当我们需要什么添加功能,就从右边中选择一个装饰。例如,我们需要缓存功能,那么需要bufferedInputStream装饰:

BufferdInputStream is = new BufferedInputStream(new FileInputStream("xxx.txt"));

假如再要DataInputStream的功能,只要在加一层:
DataInputStream dis = new DataInputStream(new BufferdInputStream(new FileInputStream));
(厄,我不甚明白这个类添加的功能是做什么用的,资料说是增加读取java原生数据的功能,不甚明白,有清楚的来补充一下,pipeInputStream跟sequenceInputStream也没用过,欢迎补充说明)
这里你可以想象成,在基本的FileInputStream.readxxx()方法在BufferedInputStream的readxxx()方法调用,并添加相应的处理。

最后说说InputStream跟reader的区别:

老实说,我只知道一个支持字节流,一个支持unicode流,除此之外有啥米性能上的不同我还真不知道,哈哈。知道的快来补充补充~

java.io包详细解说的更多相关文章

  1. java.io包中的字节流—— FilterInputStream和FilterOutputStream

    接着上篇文章,本篇继续说java.io包中的字节流.按照前篇文章所说,java.io包中的字节流中的类关系有用到GoF<设计模式>中的装饰者模式,而这正体现在FilterInputStre ...

  2. 1.java.io包中定义了多个流类型来实现输入和输出功能,

    1.java.io包中定义了多个流类型来实现输入和输出功能,可以从不同的角度对其进行分 类,按功能分为:(C),如果为读取的内容进行处理后再输出,需要使用下列哪种流?(G)   A.输入流和输出流 B ...

  3. Java:输入输出流 java.io包的层次结构

    1.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.Java的I/O流提供了读 ...

  4. java.io包下适配和装饰模式的使用

    如java.io.LineNumberInputStream(deprecated),是装饰模式(decorate)的实现: 如java.io.OutputStreamWriter,是适配器模式(ad ...

  5. 装饰者模式在JDK和Mybatis中是怎么应用的? java io包

    https://mp.weixin.qq.com/s/-bj71dBylRHRqiPorOpVyg 原创: 李立敏 Java识堂 3月10日 有一个卖煎饼的店铺找上了你,希望你能给她们的店铺开发一个收 ...

  6. java.io包的总体框架图(转)

    原文链接:java.io包的总体框架图, 便于记忆!

  7. Java.io 包(字节流)

    I/O流概述 在 Java 中,把不同类型的输入.输出源抽象为流(Stream),而其中输入或输出的数据则称为数据流(Data Stream),用统一的接口表示,从而使程序设计简单明了.流是一组有顺序 ...

  8. 【代码笔记】Java文件的输入输出(1)——Java.io包的初步理解

    Java里面文件的输入输出全部在java.io包里面. Java.io包里面所有的类都需要掌握. java.io包里面所有的东西都在上面了. 包里面的相关类.异常等树关系如下 类分层结构 java.l ...

  9. Java源码解析——Java IO包

    一.基础知识: 1. Java IO一般包含两个部分:1)java.io包中阻塞型IO:2)java.nio包中的非阻塞型IO,通常称为New IO.这里只考虑到java.io包中堵塞型IO: 2. ...

随机推荐

  1. 安装oracle 12c RAC遇到的一些问题

    (1) 安装grid软件,停止在38%很长时间不动,日志显示正常   解决方法: 由于是虚拟机安装,设置的内存为600M,关闭虚拟机,把内存调成1GB,问题解决~在38%Linking RMAN Ut ...

  2. Datagard產生gap

    本文轉載自無雙的小寶的博客:http://www.cnblogs.com/sopost/archive/2010/09/11/2190085.html 有時候因為網路或備份故障等原因,主機所產生的歸檔 ...

  3. 继续Get News List

    拿到news list 所需要的技能 json数组反序列化 iOS中有哪些集合对象 数组的遍历 Debugging with GDB json数组反序列化 id jsonObject = [NSJSO ...

  4. Java Hour 62 J2EE App 服务器

    目前略微瓶颈了,准备换工作. tomcat.weblogic.jboss的区别,容器的作用 Apache 是一个http 服务器. Tomcat 是一web 应用程序服务器,支持部分的j2ee. Jb ...

  5. Windows系统上安装多个版本jdk,修改环境变量不生效

    本机已经安装了jdk1.6,而比较早期的项目需要依赖jdk1.5,于是同时在本机安装了jdk1.5和jdk1.6. 安装jdk1.5前,执行 java -version 得到java version ...

  6. Intent传递对象的两种方法(Serializable,Parcelable) (转)

    今天讲一下Android中Intent中如何传递对象,就我目前所知道的有两种方法,一种是Bundle.putSerializable(Key,Object);另一种是Bundle.putParcela ...

  7. android:layout_gravity和android:gravity属性的区别(转)

    gravity的中文意思就是”重心“,就是表示view横向和纵向的停靠位置 android:gravity:是对view控件本身来说的,是用来设置view本身的文本应该显示在view的什么位置,默认值 ...

  8. sublime text 2中Emmet8个常用的技巧

    原文链接:http://blog.csdn.net/lmmilove/article/details/9181323 因为开始做web项目,所以最近在用sublime编辑器,知道了一个传说中的emme ...

  9. 初探YAML

    YAML何许物也?在XML泛滥的情况下,YAML的出现的确让人眼前一亮,在初步学习了YAML以后,粗略的总结了一下,拿出来和大家分享.[MindMap][参考文档]YAML Specification ...

  10. HashMap合并相同key的value

    Map<String, String> map1 = new HashMap<>(); map1.put("x", "y"); map1 ...