JavaSE(一) IO类层次关系和各种IO流的用法总结

      今天把IO流的这一知点进行一下总结,因为在之前使用io流的时候,就只知道几个重点常用的IO类,比如FileInputStream,BufferedInputStream(缓冲流)等等,但是不知道它处于整个IO体系中的什么位置,对于其中的整个IO体系一点不了解,每次使用的时候都需要百度查看用法例子,这就说明自己对这块的知识有所欠缺,所以今天,来详细的分析,解剖一下IO的整个结构。

          借鉴博文:http://www.cnblogs.com/skywang12345/p/io_01.html  该博主写的非常好,自己重新写一遍是因为想按照自己的思路进行总结,方便日后自己复习。有雷同是肯定的。谢谢

                            --WZY

 

一、IO流的分类                                

    1.1、按数据流的方向分为 输入流输出流

        此输入、输出是相对于我们写的代码程序而言,

        输入流:从别的地方(本地文件,网络上的资源等)获取资源 输入到 我们的程序中

        输出流:从我们的程序中 输出到 别的地方(本地文件), 将一个字符串保存到本地文件中,就需要使用输出流。

    1.2、按处理数据单位不同分为 字节流字符流 

         1字符 = 2字节 、 1字节(byte) = 8位(bit)  、 一个汉字占两个字节长度

       字节流:每次读取(写出)一个字节,当传输的资源文件有中文时,就会出现乱码,

        字符流:每次读取(写出)两个字节,有中文时,使用该流就可以正确传输显示中文。

    1.3、按功能不同分为 节点流处理流

       节点流:以从或向一个特定的地方(节点)读写数据。如FileInputStream 

          处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装

       这里就涉及到了装饰者模式,在后面会详细讲解该模式在IO中的体现。

 

    1.4、4个基本的抽象流类型,所有的流都继承这四个。

           输入流      输出流

      字节流  InputStream  outputStream

      字符流  Reader      Writer

      inputStream:字节输入流

      outputStream:字节输出流

      Reader:字符输入流

      Writer:字符输出流

     

    1.5、总结流的分类

        看上面的几个分类,可能对于初次学io的同学会感觉到有些混乱,那什么时候用字节流,什么时候该用输出流呢?其实非常简单,举一个例子就学会了,

        1、首先自己要知道是选择输入流还是输出流,这就要根据自己的情况而定,如果你想从程序写东西到别的地方,那么就选择输出流,反之用输入流

        2、然后考虑你传输数据时,是选择使用字节流传输还是字符流,也就是每次传1个字节还是2个字节,有中文肯定就选择字符流了。

        3、前面两步就可以选出一个合适的节点流了,比如字节输入流inputStream,如果要在此基础上增强功能,那么就在处理流中选择一个合适的即可。

 

二、4个基本抽象类的继承关系分析                            

     2.1、InputStream 字节输入流

          

       2.1.1、认识每个类的功能即作用

           现在就认识一下即可,详细的功能会在后面的博客中写出来。

         ByteArrayInputStream:字节数组输入流,该类的功能就是从字节数组(byte[])中进行以字节为单位的读取,也就是将资源文件都以字节的形式存入到该类中的字节数组中去,我们拿也是从这个字节数组中拿

         PipedInputStream:管道字节输入流,它和PipedOutputStream一起使用,能实现多线程间的管道通信

         FilterInputStream :装饰者模式中处于装饰者,具体的装饰者都要继承它,所以在该类的子类下都是用来装饰别的流的,也就是处理类。具体装饰者模式在下面会讲解到,到时就明白了

              BufferedInputStream:缓冲流,对处理流进行装饰,增强,内部会有一个缓存区,用来存放字节,每次都是将缓存区存满然后发送,而不是一个字节或两个字节这样发送。效率更高

              DataInputStream:数据输入流,它是用来装饰其它输入流,它“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”

         FileInputSream:文件输入流。它通常用于对文件进行读取操作

            File:对指定目录的文件进行操作,具体可以查看讲解File的博文。注意,该类虽然是在IO包下,但是并不继承自四大基础类。

           ObjectInputStream:对象输入流,用来提供对“基本数据或对象”的持久存储。通俗点讲,也就是能直接传输对象,

 

      2.2、OutputStream 字节输出流

              

          具体分析在上面分析过了,只不过和inputStream是相对的,但作用是相同的。

      2.3、Reader 字符输入流

                

           功能也差不多,类似。这里分析一个。

           InputStreamReader:转换流  将 字节输入流  转换为  字符输入流。它是字节流通向字符流的桥梁

      2.4、Writer 字符输出流

                  

 三、装饰者模式的运用                                    

      3.1、什么是装饰者模式?

            推荐一篇博文,http://blog.csdn.net/jason0539/article/details/22713711  就详细说明了什么是装饰者模式?用我自己的话来说,就是往一个添加更多的功能,而我们首先想到的是继承,继承就很好的符合了我们的要求,不管你想加多少层的功能,都可以使用继承一层层的实现,但是这带来了一个问题,一旦我需要改变我的需求,那么我就需要往源码中改东西,再就是在这个继承链中某个类做一些修改,这不符合我们的设计模式思想,所以就有了装饰者模式,装饰者中拥有被装饰者的实例,然后有什么具体的装饰我们都另写一个类来继承该装饰者,当我们需要该装饰时,就new出该类来,然后将其被装饰者当作参数传递进去。

                   

          关说可能没理解那么清楚,现在来看看一个具体的实例。比如,我们需要制作一份鸡腿堡,流程是怎样的呢?看下图

              1、先有基本原料,也就是两块面包,这是不管做什么汉堡都需要的,

              2、做什么汉堡,取决于加什么材料,比如生菜,鸡肉等,所以根据材料来做汉堡,想做什么汉堡就加什么材料

              3、所有材料加完之后,直接计算价格即可

            这样使用装饰者模式,是不是比一直使用继承方便的多的多呢?换一种汉堡,也不需要改源码,什么也不需要,希望你能够理解清楚其中的思想。

                    

 

      3.2、io流中的装饰者模式的运用

            画张图,在结合源码和自己写的代码来看。

                  

 

          到这里,应该可以对前面的处理流和节点流有所理解了把,其实处理流就是一个具体的装饰者,而节点流就是被装饰者。

 

四、总结                                        

       4.1、应该知道io流的各种类的结构关系,平常我们使用的io类是处于什么样的位置,是一个什么样的流(节点流还是处理流,输入流还是输出流,字节流还是字符流)

       4.2、装饰者模式在io流中的运用和什么是装饰者模式

       4.3、为什么在使用io流时会将是那样的格式进行编写,将一个流的实例放入另一个流的构造方法中?

 

posted @ 2017-05-30 16:37  有梦想的老王  阅读(4411)  评论(1编辑  收藏