对于所有的的编程语言来说,一个设计好的IO系统至关重要。和c++一样,java的IO也使用流这个概念,它表示任何 有能力产生数据的数据源对象或者有能力接收数据的接收端对象,”流“屏蔽了实际IO设备处理数据的细节。
java的IO库分成输入(Inputstream,Reader)和输出(outputstream,writer)两部分,同时又有面向字节(前者)和面向 字符(后者)两类。这样总体的说貌似很简单,但是java的IO对象库一点也不简单,并没有一个较简洁的方式来完成 对单一流的控制,而往往要创建多个对象。
首先说明所有的IO类都继承自上述四种基类,下面来具体说说:
Inputstream & Outputstream
InputStream的数据源类: ByteArrayInputStream 字节流,构造器参数:缓冲区 StringBufferInputStream String对象转化为流,参数:字符串(已弃用) FileInputStream 从文件中读取信息,参数:文件名字符串 PipedInputStream 管道化数据,参数:PipedOutputStream 上述的几种数据源中,最常用的就是FileInputStream,因为我们有时候更多的是跟文件打交道,管道有时会 在多线程中使用。
OutputStream决定了数据的去向,与上文中的Input类是对应的,但是没有StringbufferOutputStream类。
从类的定义可以看出来上述类是与缓冲区或者文件直接打交道的,所以他们是读出数据的第一步,也是写入数据的 最后一步,他们直接由两个基类派生而来。
FilterInputStream & FilterOutputStream
它们是javaIO库的装饰抽象类,继承自上文中的两个基类,其中FilterInputStream可以内部修改InputStream 的行为,它有两种基本方式:
DataInputStream 利用可移植的方式从流中读取基本数据类型(int,char,long等)
BufferedInputStream 使用缓冲区
他们的构造器参数均为InputStream,但是要产生上述两种数据流对象可以这样使用:
new BufferedInputStream(new FileInputStream("TestEOF.java"));
这样被称作为数据流的转移。
Output与上文基本上类似,只不过多了个PrintStream,用于控制格式化输出,可以指示是否清空缓存。
Reader & Writer
首先说明这两个类库也是IO中的基类,但是他们是面向字符的,是为了与国际化接轨。这里作者建议:在编写java IO程序的时候尽量用Reader与Writer。当然我们也可以实现上述两种类库的转换,即InputStreamReader把InputStream 转换为Reader,OutputStreamWriter把OutputStream转换为Writer。
它也有像上文中一样的两层结构:
数据源:
Reader - InputStream(通过InputStreamReader) FileReader - FileInputStream StringReader - StringBufferInputStream
更改流的行为:
BufferedReader ---- BufferedInputStream BufferedWriter ---- BufferedOutputStream DataInputStream 没有变化
有一点需要提醒在使用readLine的时候,应该使用BufferedReader,而不是DataInputStream,但是其他情况应首选 后者。
在输出方面,我们应该统一了,使用PrintWriter能带来很大的便利,它既能接收Writer,也能接受OutputStream 对象,这样使用是不是觉得一下子简单了:
PrintWriter out = new PrintWriter("fileoutput.out")
out.println();
out.fllush() 冲洗缓存,在PrintWriter后加入true参数效果一样
还有对于流不得不说一说其API:
readLine() 读取一行
read() 读取一个字节或字符
readByte() 一个字节一个字节地读
available() 查看可取的字符数
writeInt(readInt) 读写整数,针对DataInputStream与DataOutputStream
writeDouble(readDouble) 读写浮点数
writeUTF(readUTF) 读写UTF编码的字符串
关于java的IO基础框架已经差不多了,至于具体的应用就具体情况具体讨论吧。