posts - 2,  comments - 0,  trackbacks - 0

  一直以来对IO这块的东西认识都不是很清楚。每次涉及这块的东西,一般都找点现成的代码复制粘贴一下。这可不好,于是静下心来好好弄一下。

 

 

什么是IO?

    一提起IO给人的感觉就比较复杂(不过确实也挺复杂的),可能是学C的时候吓怕了,呵呵。不过,理一下思路还是比较清晰的。在Java里,IO说白了就是对读、写的一种抽象。没有什么其他的复杂的东西。至于读什么、写什么,那就看你想读什么、想写什么,由自己控制了。

 

 

读什么?写什么?

看看下面这个图会清楚很多(只用看InputStream就行,OutputStream一样):

 

 

 

     大家可以看一下直接继承InputStream的几个类ByteArrayInputStream、FileInputStream、StringBufferInputStream(PipedInputSteram和SequenceInputStream一般不用)。呵呵,看看这几个类的构造函数就明了了。第一个是把byte数字作为IO源读取byte数组里的东西,第二个是把文件作为IO源读取文件里的东西,第三个是把String作为IO源读取String里面的东西。这么看这几个IO实在简单。说白了就是从byte数组、文件、String按字节读取罢了.....

    一句简单的话说:IO体系第一级继承的几个类解决了从哪儿读或者写到哪儿的问题

 

 

怎么读?怎么写?

    试想一下,现在要读一个几百兆的文件,怎么读呢?是一下子把整个文件都读到内存慢慢分析呢,还是每次读只读一个字节逐个分析呢?显然两个都不好,于是我们想到了缓冲。所以IO体系上有了BufferedInputStream。再想一下,现在你想写一个“3.1415926”到文件里怎么写?总不能自己把这个数的二进制形式写出来,转成byte数组写到文件里吧。即便写进去了读的时候怎么读啊?谁知道你写进去的是数字而不是其他字符呢?

    于是针对怎么读Java IO体系上出现了一个分支FilerInoutStream(FilterOutputStream)。继承了这个类的几个类各自对怎么读、写提供了不同的支持。Buffered提供了缓冲,LineNumber提供了对不同类型数据的读写。

    还是一句话:IO体系的第二级继承解决了怎么读、怎么写

 

 

以不变应万变

    说IO不能不说他的Decorator(装饰)模式。此模式在这里的应用确实很经典!从上面两段的分析看来Java的IO就是分成两部分从哪儿读(写)和怎么读(写)。想想看,一个数据源可能需要不同的读写方式、而不同的数据源都可能需要同一直读写方式。于是这里的组合方式是一种乘积。n个数据源×n中处理方式×(n-1)处理方式(有时候可能涉及多种处理方式的叠加)=n^3。想想看,要是一个一个写还不写死......

    从IO体系的根看,InputStream(OutputStream)提供了最根本的read(write)方法。各子类提供各自实现。而得益于Decorator,各子类还可以把自己的处理方式加到read(write)的前后,形成一种处理方式的叠加。

    JDK这部分的代码比较简单。看一下就大概知道Decorator怎么实现的了。

 

 

追根溯源

     我们见到的IO最大的应用一个应该是数据的持久化,FileinputStream(FileOutputStream)已经实现了。而另一个则是网络传输。之前我就很想知道IO是怎么在网络上实现传输的?还有上面说的几个IO都不存在“阻塞”问题,那么IO的阻塞实在哪儿产生的呢?

     找了半天对于找到了下面一句:

     class SocketInputStream extends FileInputStream

     再追下去就找到了一些native方法,这个就超出我能力之外了。不过可以猜想,底层的东西应该就是C的一些文件读写了。这个就不是Java的问题:)目前暂时这么认为,以后或许能发现一些新的东西。

 

 

根深蒂固的痛——国际化

     编码问题不仅是Java头痛的问题,也是每一个用Java的人都头痛的问题。IO也不例外。InputStream(OutputStream)体系都是针对字节(byte)进行读写的。这样的问题是字节可能是没有意义的,只有几个字节联合转换才能得到有意义的东西。所以如果是字节还要再次进行编解码才能得到我们想要的东西。

    为了避免这个麻烦,字符体系(Read、Write)产生了。他们可以对流进行编解码,这样可以直接得到用户想要的东西。两个体系大大体上都是对应的。再多的东西我也没有深入了解了:)

    还有一个要提的是,什么时候用字符、什么时候用字节呢?TIJ里有交代:大部分时候用字符,字符不行的时候再考虑字节。呵呵,挺简练的。

 

 

日新月异

    nio应该是老掉牙的东西了。不过对于我这个初始IO的人来说还有待进一步了解。目前知道两点:上面的IO体系的底层都已经用nio重写了,所以速度上应该差不多。这样看来,一般情况下用上面的IO是没问题的。再一个是,nio最大的优势在于他的“非阻塞IO”,不过这个东东是用在网络编程的。一般也用不上。

    再新的东西就是前两天看到的一个blog,关于aio(异步IO)的大家有兴趣可以自己看看。

posted on 2006-11-25 21:26 KeepRunning 阅读(355) 评论(0)  编辑  收藏 所属分类: Java点滴

只有注册用户登录后才能发表评论。


网站导航:
相关文章:
 
<2006年11月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜