Java应用经常有逐行读取文本文件的需求,很多时候,Java应用也需要逐行地写文本文件。对于逐行读取文本文件的问题,我们是通过三种构建 BufferedReader 的方式来实现,最终利用其 readLine() 方法。那么对于Java应用中的逐行写出文件,在JDK的输入输出(I/O)包中,又提供了哪些方法呢?哪一种是最好的方法呢?本文将以代码示例的形式,提供多种逐行写文本文件的解决方案。
BufferedWriter
public static void writeFile1() throws IOException {
File fout = new File("out.txt");
FileOutputStream fos = new FileOutputStream(fout);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
for (int i = 0; i < 10; i++) {
bw.write("something");
bw.newLine();
}
bw.close();
}
这个例子使用了 FileOutputStream 来完成任务,其实,也可以使用 FileWriter 或 PrintWriter 等来替代,这些类可以很好地完成文本文件的逐行写出任务。
FileWriter
public static void writeFile2() throws IOException {
FileWriter fw = new FileWriter("out.txt");
for (int i = 0; i < 10; i++) {
fw.write("something");
}
fw.close();
}
PrintWriter
public static void writeFile3() throws IOException {
PrintWriter pw = new PrintWriter(new FileWriter("out.txt"));
for (int i = 0; i < 10; i++) {
pw.write("something");
}
pw.close();
}
OutputStreamWriter
public static void writeFile4() throws IOException {
File fout = new File("out.txt");
FileOutputStream fos = new FileOutputStream(fout);
OutputStreamWriter osw = new OutputStreamWriter(fos);
for (int i = 0; i < 10; i++) {
osw.write("something");
}
osw.close();
}
总结
一个问题有多种解决方案,这四种解决方案的优缺点是什么呢?我们看看 Java Doc 是如何说的:
FileWriter 是一个写文本文件的便利类。该类的构造函数采用JVM中的默认字符编码集(utf8,gbk),采用JVM中默认的字节缓存大小,这两个熟悉无法被修改。如果想要修改这两个重要属性,必须使用 FileOutputStream 构造一个 OutputStreamWriter。
PrintWriter 可以把一个对象转换成字符流,并且格式化打印出来。这个类实现了其父类 PrintStream 的所有打印方法。但是,这个类没有输出原始字节流的方法。如果希望可以输出字节流,需使用原始的字节流。
这四种方法的主要区别在于:首先,PrintWriter 额外提供了很多格式化输出字符串的方法,比如 println(),printf()。第二,FileWriter在任何的输出输入(I/O)出错时,都会抛出异常;PrintWriter不会抛出任何异常,它在输入输出(I/O)出错时,会设置一个 boolean 类型的标志符,需要通过 checkError()方法查询该标志位。第三,PrintWriter在每次有字节输出时,会自动调用其 flush()方法;对于FileWriter,则需要程序员手动调用其 flush()方法。