黑马程序员技术交流社区

标题: java IO流的基本流程 [打印本页]

作者: 2666fff    时间: 2015-6-4 22:33
标题: java IO流的基本流程
IO 编程的一般流程:
    1. 创建基本流
    2. 升级基本流到高级流
    3. 使用在高级流中的方法作读写操作
    4. 关闭流并释放资源


IO是计算机最重要的功能是处理数据。一个有用的计算机语言需要拥有良好的IO功能,以便让未处理的数据流入程序,让已处理的数据流出。

[size=13.3333330154419px]与其他语言相比,Java的IO功能显得复杂。在其他语言中,许多IO功能(比如读取文件),是被封装好的,可以用一两行程序实现。在Java中,程序员往往需要多个层次的装饰(decoration),才能实现文件读取。

[size=13.3333330154419px]相对的复杂性带来的好处是IO的灵活性。在Java中,程序员可以控制IO的整个流程,从而设计出最好的IO方式。我们将在下文看到更多。

[size=13.3333330154419px]我们先来研究一个文件读取的例子:

[size=13.3333330154419px]

  1. import java.io.*;

  2. public class Test
  3. {
  4.     public static void main(String[] args)
  5.     {
  6.         try {
  7.             BufferedReader br =
  8.               new BufferedReader(new FileReader("file.txt"));

  9.             String line = br.readLine();

  10.             while (line != null) {
  11.                 System.out.println(line);
  12.                 line = br.readLine();
  13.             }
  14.             br.close();
  15.         }
  16.         catch(IOException e) {
  17.             System.out.println("IO Problem");
  18.         }
  19.     }
  20. }
复制代码

装饰器与功能组合

[size=13.3333330154419px]程序IO的关键在于创建BufferedReader对象br:

[size=13.3333330154419px]    BufferedReader br = new BufferedReader(new FileReader("file.txt"));

[size=13.3333330154419px]在创建的过程中,我们先建立了一个FileReader对象,这个对象的功能是从文件"file.txt"中读取字节(byte)流,并转换为文本流。在Java中,标准的文本编码方式为unicode。BufferedReader()接收该FileReader对象,并拓展FileReader的功能,新建出一个BufferedReader对象。该对象除了有上述的文件读取和转换的功能外,还提供了缓存读取(buffered)的功能。最后,我们通过对br对象调用readLine()方法,可以逐行的读取文件。

[size=13.3333330154419px](缓存读取是在内存中开辟一片区域作为缓存,该区域存放FileReader读出的文本流。当该缓存的内容被读走后(比如readLine()命令),缓存会加载后续的文本流。)

[size=13.3333330154419px]BufferedReader()是一个装饰器(decorator),它接收一个原始的对象,并返回一个经过装饰的、功能更复杂的对象。修饰器的好处是,它可以用于修饰不同的对象。我们这里被修饰的是从文件中读取的文本流。其他的文本流,比如标准输入,网络传输的流等等,都可以被BufferedReader()修饰,从而实现缓存读取。


更多的组合

[size=13.3333330154419px]事实上,Java提供了丰富的装饰器。FileReader中合并了读取和转换两个步骤,并采用了常用的默认设置,比如编码采取unicode。我们可以使用FileInputStream + InputStreamReader的组合来替代FileReader,从而分离读取字节和转换两个步骤,并对两个过程有更好的控制。

[size=13.3333330154419px](当然,FileReader的使用更加方便。InputStreamReader是将FileInputStream转换成一个Reader,用于处理unicode文本)

[size=13.3333330154419px]

[size=13.3333330154419px]箭头表示数据流动方向

[size=13.3333330154419px]

[size=13.3333330154419px]流的读写来自于四个基类: InputStream, OutputStream, Reader和Writer。InputStream和Reader是处理读取操作,OutputStream和Writer是处理写入操作。它们都位于java.io包中。继承关系如下:

[size=13.3333330154419px]

[size=13.3333330154419px]

[size=13.3333330154419px]java.io

[size=13.3333330154419px]

[size=13.3333330154419px]此外,IOException有如下衍生类:

[size=13.3333330154419px]

[size=13.3333330154419px]IOException

[size=13.3333330154419px]

[size=13.3333330154419px]Reader和Writer及其衍生类是处理unicode文本。如我们看到的Buffered Reader, InputStreamReader或者FileReader。

[size=13.3333330154419px]InputStream和OutputStream及其衍生类是处理字节(byte)流。计算机中的数据都可以认为是字节形式,所以InputStream和OutputStream可用于处理更加广泛的数据。比如我们可以使用下面的组合来读取压缩文件中包含的数据(比如整数):

[size=13.3333330154419px]

[size=13.3333330154419px]箭头表示数据流动方向



[size=13.3333330154419px]我们从压缩文件中读出字节流,然后解压缩,最终读出数据。

写入

[size=13.3333330154419px]写入(write)操作与读取操作相似。我们可以通过使用装饰,实现复杂的写入功能。这里是一个简单的写入文本的例子:

[size=13.3333330154419px]

  1. import java.io.*;

  2. public class Test
  3. {
  4.     public static void main(String[] args)
  5.     {
  6.         try {
  7.             String content = "Thank you for your fish.";

  8.             File file = new File("new.txt");

  9.             // create the file if doesn't exists
  10.             if (!file.exists()) {
  11.                 file.createNewFile();
  12.             }

  13.             FileWriter fw = new FileWriter(file.getAbsoluteFile());
  14.             BufferedWriter bw = new BufferedWriter(fw);
  15.             bw.write(content);
  16.             bw.close();

  17.         }
  18.         catch(IOException e) {
  19.             System.out.println("IO Problem");
  20.         }
  21.     }
  22. }
复制代码





作者: tinlen    时间: 2015-6-5 23:26
刚学到io流,赞一个




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2