JAVA I/O操作那些事之输入输出流简介(二)
Reader和Writer
首先,我们要明确一点,Reader和Writer不是为了取代InputStream和OutStream的,而且他们之间在代码上可以看到,也没有什么直接的关系。两者最大的区别呢,是Reader和Writer提供兼容Unicode与面向字符的I/O功能,而后两者则是提供面向字节形式的I/O操作。(1个字符=2个字节)
有的时候,我们需要将来自于字节层次结构中的类和来自于字符层次结构中的类结合起来使用,这时候,从应用场景上就可以看到,这是典型的适配器模式。。。适配器类,InputStreamReader可以把InputStream转化为Reader,而OutputStreamWriter可以把OutputStream转换为Writer。
一个简单的例子
BufferedReader in = new BufferedReader( new FileReader(fileName)); String s = null; StringBuilder sb = new StringBulider(); while((s=in.read.readLine())!=null) { sb.append(s).append("\n"); } in.close();
上面这段代码其实很简单了,只所以拿出来,是因为红色部分,注意,我们在每行数据后又加了换行符,因为readLine()方法已经把换行符删掉了。。。
自我独立的类:RandomAccessFile
这个类适用于由大小已知的记录组成的文件,我们可以使用seek()将记录从一处转移到一处,然后对其进行读取或者修改。 PS:对于文件中的记录,其大小不一定非得要求相等,当然这种情况下我们需要确定文件中每个记录的大小以及他们所在的位置。
为什么说这个类是独立的呢,因为它不继承于InputStream和OutputStream,其除了implements DataOutput, DataInput这两个接口外,与其他的输入输出流就没什么联系了。他跟其他I/O类型最大的不同点再于:使用它我们可以再一个文件内部向前和向后移动。
下面是JDK中关于其的部分源码,主要是构造函数
public RandomAccessFile(String name, String mode) throws FileNotFoundException { this(name != null ? new File(name) : null, mode); }
最后强调一下,使用这个类的时候,我们必须知道文件的排版(其实就是每条记录的大小和位置),只有这样才能正确的使用它。