java中有两套IO,一套是普通的IO,即jdk1.4之前就包含的IO,另一套是jdk1.4包括进来的nio。本文指的是普通的IO。java中的IO是基于流的。流的概念可以这样理解,即数据好像实在一根管子里面流动,而管子的两端连接什么,则需要根据具体的输入输出需要来确定了。比如说,我想从文件输入到屏幕显示,则管子的一端(输入端)连接的是文件,另一端连接的是屏幕。这个比方可能不是很准确,但目前先大概这样理解了:-)。

    java的io有两类,一类是基于字节流的,基类是InputStream/OutputStream,另一类是基于字符流的,基类是Reader/Writer,注意基于Java的字符使用Unicode表示的,所以Reader/Writer的读写操作都似乎基于双字节的Unicode代码单元。

    下图表示了Java io的结构(图片来自:http://www.unix.com.ua/orelly/java-ent/jnut/figs/JN3_1101.gif):

    在学习时应该注意的是,基于字节的io和基于字符的io是有一定的对应关系的,掌握这些对应关系,可以更快的掌握java io。

    基于字节流的输入的类:

  1) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用

2) StringBufferInputStream:把一个String对象作为InputStream

3) FileInputStream:把一个文件作为InputStream,实现对文件的读取操作

4) PipedInputStream:实现了pipe的概念,主要在线程中使用

5) SequenceInputStream:把多个InputStream合并为一个InputStream

基于字节流的输出的类:

1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中

2) FileOutputStream:把信息存入文件中

3) PipedOutputStream:实现了pipe的概念,主要在线程中使用

4) SequenceOutputStream:把多个OutStream合并为一个OutStream

基于字符流的输入的类:
  1) CharArrayReader:与ByteArrayInputStream对应
  2) StringReader:与StringBufferInputStream对应
  3) FileReader:与FileInputStream对应
  4) PipedReader:与PipedInputStream对应

基于字符流的输出的类:
  1) CharArrayWrite:与ByteArrayOutputStream对应
  2) StringWrite:无与之对应的以字节为导向的stream
  3) FileWrite:与FileOutputStream对应
  4) PipedWrite:与PipedOutputStream对应

  以字符为导向的stream基本上对有与之相对应的以字节为导向的stream。两个对应类实现的功能相同,只是在操作时的导向不同。如 CharArrayReader和ByteArrayInputStream的作用都是把内存中的一个缓冲区作为InputStream使用,所不同的 是前者每次从内存中读取一个字节的信息,而后者每次从内存中读取一个Unicode字符(2个字节)。

InputStreamReader和OutputStreamReader:把一个以字节为导向的stream转换成一个以字符为导向的stream。

java中基于字节流的io还有一个重要的概念,装饰类。即上图中InputStream和OutputStream的子类中带有Filter*类的子类,通过这些装饰类可以给io添加新的功能。一个典型的应用实例便是如果想要一个基于字节流的文件输入,而又想提高效率而采用缓冲的话,可以按照以下代码实现:

File f = new File("c:\\test.dat);

FileInputStream fis = new FileInputStream(f);

BufferedInputStream bis = new BufferedInputStream(fis);

然后就可以对这个流采用带有缓冲的输入了。下面详细介绍一下装饰类:

InputStream的装饰类:
  1) DataInputStream:从stream中读取基本类型(int、char等)数据。
  2) BufferedInputStream:使用缓冲区
  3) LineNumberInputStream:会记录input stream内的行数,然后可以调用getLineNumber()和setLineNumber(int)
  4) PushbackInputStream:很少用到,一般用于编译器开发

OutputStream的装饰类
  1) DataIOutputStream:往stream中输出基本类型(int、char等)数据。
  2) BufferedOutputStream:使用缓冲区
  3) PrintStream:产生格式化输出

在基于字符流的io中,与上述的基于字节流的装饰类的对应关系如下:
       Reader的子类:
       1) 没有与DataInputStream对应的类。除非在要使用readLine()时改用BufferedReader,否则使用DataInputStream
  2) BufferedReader:与BufferedInputStream对应
  3) LineNumberReader:与LineNumberInputStream对应
  4) PushBackReader:与PushbackInputStream对应

Writer的子类:
  1) BufferedWriter:与BufferedOutputStream对应
  2) PrintWriter:与PrintStream对应

如果想随机读写文件,可以使用RandomAccessFile类:
  1) 可通过RandomAccessFile对象完成对文件的读写操作
  2) 在产生一个对象时,可指明要打开的文件的性质:r,只读;w,只写;rw可读写
  3) 可以直接跳到文件中指定的位置

参考:

彻底明白 Java 语言中的IO系统 http://dev.yesky.com/105/7570105.shtml

精通Java网络编程 汪晓平 清华大学出版社 2005 9


文章来源:http://tangwei312tom.blog.163.com/blog/static/22473192200881410343504