java源码之 io 流源码解读(二)

    休息了一会,纠结了好一会。   究竟是这会写了还是明天再继续写。  最后还是敲定就今晚写了吧。  明天有明天的安排嘛。

    嗯嗯,决定了就不再拖沓,接着上一章继续写:

        之前已经讨论了InputStream 的前两个重要的实现类吧。   还有最后一个那就是:ByteArrayInputStream。   这个类算是比较好理解的。  并且它是实现了核心方法read().请看图:

        

            

 

    这里说明一点,为什么要做一个与运算呢?   额,因为它的对应的写方法弄了一个与运算,具体有什么用不是很清楚,大概是跟那个原码反码补码相关,但是理解不深刻。

    所以这里就很巧妙了。作为一个基本流中的两大支撑,一里一外,相互勾结。   共同完成用户的任务目标,岂不是很爽快。  FileInputStream负责外部,ByteArrayInputStream负责内部。(但是注意谁给他提供读取源呢,因此在实例化的时候就得给他指定了。)。

    尽管相互之间有差别,但是它们毕竟从表现上来看,还是基于同一个基础,那就是byte字节,也就是所谓的基本流。但是长江后浪退前浪,前浪死在沙滩上。Reader粉墨登场;

    Reader作为四大抽象基类之一,自然有着它不可动摇的江湖地位。虽然披上了包装类的外衣,但是其实Reader与基本流并没有直接的联系,比如实现接口或者依赖,或者继承关系之类的。 包装类的原因大概是因为它的子类实现都是依赖相应的基本流吧。  依然还是按照时间线开始展开: 

    第一个入手的是BufferedReader。 顾名思义,其自然是实现了一个缓冲的作用,相应的有它作为缓冲所需具备的条件。  至于它的输入源嘛。。   比较狡猾哈,依赖了它的父类Reader,自己当甩手掌柜去了。   

    第二个则是我们平常用的最多的包装类了,那就是InputStreamReader,它依赖的是它相应的基本流,InputStream。 而我们一拍脑门,哎呀妈呀这不正是基本流中抽象基类嘛,也就是说,所有的基本流都是能包装的嘿嘿嘿。但是包装也要看一下怎么个包装法吧!   嗯,分析源码发现它依赖了一个叫做StreamDecoder的类,继承自Reader,同时依赖于Charset与CharsetDecoding。 故名思意也就是解码嘛,或者说按照相应的编码解码。  具体的解码流程就没看了,一是没时间,二是水平不够。这也是包装流的吸引人的地方吧。   但是大概因为问道有先后,术业有专攻吧,它还有一个子类专门负责处理外部的读取工作的包装,也就是FileInpuStream。它也是依赖于相应的基本流FileInputStream的。 

    最后一个则是包装流中的最后一个输入流了,那就是StringReader,很容易想到它就是读取String类型,也就是字符串类型的流。看看它的核心方法:

    

    

    另外可以看看它的属性:

        

        可以简单的知道,它依赖于String类作为它的一个容器吧。   同样的,它的数据源也是要在实例化的时候被指定,是在java内部进行的操作。   同时,String的本质又是一个 char[],因此跟它们包装流的属性是相合的。   

    至此,关于基本输入流与包装输入流都已经粗看完毕。  做个总结:

        1.基本输入流我的理解分为三部分,从java外部读取执行读取任务的FileInputStream,从java内部读取的ByteArrayInputStream,以及将读取方法托管给它父类的FilterInputStream(包括了BufferInputStream和DataInputStream)和将方法托管给包装流的ObjectInputStream。同时,它们在表现上都是以byte作为基本单位。

            2.包装输入流我的理解也分为三类吧,好记一点。   第一个就是将读取方法托管给它父类的BufferedReader, 同时它的数据源也是实例化所提供。   第二个是StringReader,自己负责自己的读取,数据源实例化的时候提供。   第三个为与基本流打交道的InputStreamReader及其子类FileInputStreamReader。    它们则在相应基本流的读取方法中加了个包装,将以byte为基本单位的转化为了以char为基本单位,最终还是要把任务推到FileInputStream和ByteArrayInputStream头上。  同时,它们三者在表现上都是以char作为基本单位。 

            3.不论是包装输入流还是基本输入流,用户交互时并不用理会它的组成,它们的某个方法的具体实现,或者它的内部有哪些属性,哪些是公有的我们可以调用的,哪些是私有的。  我们需要的关心的只是它是否能完成我们的功能。   以及我们该如何调用它来完成我们的功能。   我们直接能知道的有四种调用方式,单字节读取,多字节读取,单字符读取,多字符读取。   针对单字节或者单字符读取的,我们只需定义相应的变量byte或者char接收,接收到的就是我们需要的。   而对于多字节和多字符的时候,我们则要定义我们需要取得的相应变量的数组byte[]或者char[],以参数的方式进行过程调用,返回的值为我们读取的位置还是什么好像,而我们需要的信息则乖乖的躺在了数组里面了。 

        输入流差不多就这些理解了。但是没想到写笔记也还是挺花时间和精力的,本来想昨晚写完的,发现有一点不切实际。  现在才把输入流介绍完。  今天的天气为阴天,刮大风。  但是我的心情却十分晴朗,大概是因为知道自己需要忙着什么,并且正在忙着什么吧。

        这里借用教学楼每天路过都能看到的一句名言自勉一下: 

                Genius always means hard-working in all one's life。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值