Java的文件IO机制


  Java有一个庞大的I/O系统,文件处理只不过是这个系统的一个子系统。文件的I/O系统整体上说都是这样的方式:数据是在程序和文件之间传递的,程序指程序里的存数据的变量或常量,文件指一个File对象。以从文件读字节为例,就是首先提供一个连通二者(程序和文件)的管道,管道只是个隐喻,专业术语叫做流,程序与管道的连通是浑然天成的,因为管道对象一定是在特定的程序里生成的,这个对象可以很自然的使用程序里的变量或常量。而文件和管道的连通是需要特别指定的。连通哪个文件一般是由File对象或一个字符串确定的。

  这个管道很神奇,在它上面可以施加各种魔法(就是能完成某种功能的方法),能施加什么样的魔法取决于管道的特性,管道的种类很多,但是分类很清晰,只有两大类:基础管道和功能管道,对应到Java术语里就是节点流和处理流,基础管道是根基,提供了少量且重要的操作,功能管道是锦上添花的,提供了更多的方法,提高了开发效率,而且一个基础管道可以套上好几层功能管道,对于每一个功能管道来说,它只能套在确定类型的基础管道上,其实这个道理很容易明白,看看API里对这些流类的命名就能看出来功能管道和基础管道是有对应关系的。对于文件操作来说基础管道有四种,分别是FileInputStream,FileOutputStream,FileWriter,FileReader。一个基础管道的名字包含了3个方面的内容,以FileInputStream为例,File说明了交换数据的一端是文件,因为另一端一定是程序了,所以不需要指定,Input说明了数据的流向,是流向程序的,Stream说明了交换的数据基本单位是字节,就是说把数据流当做字节流。同样可以分析出FileWriter的作用,这个名字有File和Writer组成,貌似只能说明两方面的内容,但是Writer包含了写出字符的意思,也就是说数据流向是程序->文件,交换数据的基本单位是字符,把数据流当做字符流。

  我们考虑一个简单的程序,把草帽海贼团成员的名字输入到一个文件straw.txt里,考虑下大致的流程:首先把名字存到一个字符串数组里,把该数组的内容输入到straw.txt里,也就是确定了数据流向:程序->文件,又因为传的内容是字符串,为了简单选用FileWriter作为基础管道。接下来考虑选什么作为功能管道,因为要把字符串写到文件里,查阅API后选取PrintWriter比较合适。因为这个类提供了println(),很适合把字符串输出到文件中。输出完成后不要忘了关闭流,也就是关闭管道,打开一个资源就要记得关闭这个资源,这是一个好的编程习惯。代码如下:

  代码

  import java.io.*;

  public class FileDemo{

  public static void main(String[] args) throws Exception{

  String names[]={"Luffy","Nami","Zoro","Sanji","Chopper","Ussop","Robin","Brook","Franky"};

  FileWriter fw=new FileWriter("straw.txt");

  PrintWriter pw=new PrintWriter(fw);

  for(int i=0;i<names.length;i++){

  pw.println(names[i]);

  }

  pw.flush();

  pw.close();

  }

  }

  关于代码说明一点,在main()里抛出异常只是为了代码写起来简单,但是这种方式不好,把异常处理机制当成了摆设,没有让该机制起到编写强壮代码的作用,java的IO操作中有很多都会抛出异常,所以这类代码写起来会有大量的try-catch-finally语句块出现。文件IO操作的原理不难,但是用的怎么样取决于对API的理解。基础管道的选取是根据题目需要的,而功能管道的选取体现了你对API的掌握程度,若选取的功能管道不同,实现同样的操作复杂度就会有区别。

相关内容