• Java I/O总结——InputStream


    http://www.moandroid.com/?p=1435


    Java I/O总结——InputStream

    By: 海市蜃楼 | In: Android开发

    22 十一 2009

    在前面介绍了Decorator(装饰)模式, 让我自己想起了刚开始工作时那段“痛并快乐”的学习时光。在学习Android网络方面,也发现网络方面的很多内容都与Java I/O有关,因此暂时先停下Android网络方面的学习,把Java I/O完整的学习下。我们将按照基类的顺序:InputStream、OutPutStreamReaderWriter来分别对Java I/O加以总结。

    在这里强调以下2点:

    • 如果你对设计模式中的Decorator(装饰)不是很了解,请仔细阅读:从new BufferedReader(new InputStreamReader(conn.getInputStream()))想到的,在这篇博客中,我们详细介绍了Decortor(装饰)模式。在了解了Decorator(装饰)后,我们对学习Java I/O的学习会容易很多,因为Java I/O的核心就是采用了Decorator(装饰)模式。
    • Java I/O系列的博客是我在学习Java I/O的基础上,对Java I/O的总结,关于Java I/O方面的基础知识,我们在这里不详细说明。如果你对Java  I/O完全不了解,请先找些关于Java I/O方面的资料简要阅读下。在简要学习的基础上,我们将Java I/O方面的资料整理,帮助大家对Java I/O的知识更加清晰些。

    Java I/O相关的包,如下表格所示:

    java-io

    在这里,我们主要介绍java.io包。

    流的分类,如下图所示:

    流的分类
    过滤流就是采用了Decorator(装饰)模式,后面我们会为大家详细说明。

    Java I/O的设计原则(Decorator(装饰)模式)

    Java I-O库的设计原则

    java.io.InputStream类总结

    首先学习基类java.io.InputStream(读取一系列字节的对象),以及在它基础上派生出来的子类,类结构图如下图所示(单击查看大图片):

    InputStream

    InputStream是一个抽象类,是所有数据形式为字节的输入流的父类,为基于字节的数据输入定义了基本操作方法。实际 上,InputStream的子类大部分都没有增加任何其他的接口函数(在上面的类结构图中就可以发现),因此在看InputStream子类的时候,我 们主要学习其构造函数。

    Java I/O中是如何采用Decorator(装饰)模式的呢?下面为大家详细说明,看到FilterInputStream类(也就前面说的过滤流,后面你会 发现更多的过滤流),你是否发现了?对,就是FilterInputStream类,她就相当于Decorator(装饰)模式中的Decorator 类,而且的BufferedInputStream、DataInputStream、PushbackInputStream则相当于是 ConcreateDecorator,如下图所示:

    Component-UML

    那么Java I/O中到底是如何使用的了?Decorator(装饰)模式的主要意图是:动态地给一个对象添加一些额外的职责,这句话很抽象,我们结合Java I/O举个具体的例子:比如说我们读取文件,首先打开文件获取到File,然后我们再创建一个FileInputStream,然后读取文件。读取文件是 一个很费时的操作,尤其是需要多次的读写文件。

    自己的一点经历与大家分享:在一次C++编程的时候,需要打开文件然后每次读取一小段数据,后来发现整个程序的效率比较低,通过测试代码发现,对数 据的读取方面占用太多的时间。尽管C++对文件的读取中实现了缓冲机制,但是好像这个缓冲区域比较小,然后通过_setbuf()函数增大缓冲区,发现程 序的数度居然提升了很多。

    那么在Java中采用面向对象的思想:BufferedInputStream实现了对数据读取的缓冲机制,通过FileInputStream来 读取数据,BufferedInputStream将已经读取的数据存储到缓冲区,BufferedInputStream相当于对 FileInputStream进行了“装饰”。

    File file = new File(“c:\\moandroid.txt”,true);
    InputStream is = new BufferedInputStream(new FileInputStream(file));
    long length = file.length();
    if(length>Integer.MAX_VALUE)
    {
    System.out.println(“source file is too large”);
    return ;
    }
    byte[] bytes = new byte[(int)length];
    int offset = 0,numRead = 0;
    while( offset<bytes.length && (numRead = is.read(bytes,offset,bytes.length-offset))>= 0)
    offset += numRead;
    if(offset<bytes.length)
    throw new IOException(“Could not completely read file”+file.getName());
    is.close();

    DataInputStream类的功能则更加强大,其在InputStream类的基础上增加了很多读取函数的接口,举个例子如下:

    InputStream is = null;
    try
    {
    File file = new File(“c:\\moandroid.txt”,true);
    is = new DataInputStream(new FileInputStream(file));
    int intData = is.readInt();
    boolean boolData = is.readBoolean();
    }
    catch(FileNotFoundException e)
    {
    e.printStackTree();
    }
    catch(IOException e)
    {
    e.printStackTree();
    }
    finally
    {
    if(is!=null)
    {
    try{is.close();}
    catch(IOException e){}
    }
    }

    这里补充说明:DataInputStream读取的顺序必须和实际数据存储的顺序一致,否则会出现IOException。

    上面的代码可以使用如下图来表示,更加的直观:

    Input Stream Chain
    大家再去仔细看下Decorator(装饰)模式中的例子:一个具有边框与滚动条的文本显示窗口,是不是很相似!

    总结说明

    整个java.io的核心都是采用了Decorator(装饰)模式, 理解了Decorator(装饰)模式,对Java I/O的学习是不是更加简单了,这里我只是将自己的学习的笔记整理后与大家分享。java.io.InputStream类结构图,建议大家打印出来后, 在以后使用时候在拿出来看下,就知道如何使用了。当然这张类图结构还不完整(缺少其他一些类),打印出来后自己补充说明,把这张类图逐步完善。

    相关文章



  • 相关阅读:
    从三道题目入门frida
    APP 抓包(应用层)
    安卓开发--探究碎片Fragment
    centos7-查询内存/硬盘等详细信息
    网页视频下载神器
    error: C++ preprocessor "/lib/cpp" fails sanity check错误解决方法
    make源文件时出现 /usr/bin/ld: cannot find -lstdc++ 错误
    安装docker后修改docker文件目录
    centos集群中各节点如何实现时间同步?
    redhat7.5 yum不能用
  • 原文地址:https://www.cnblogs.com/lexus/p/2195870.html
Copyright © 2020-2023  润新知