一直以来对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 @
2006-11-25 21:26 KeepRunning 阅读(354) |
评论 (0) |
编辑 收藏