在 Java 中,FileWriter 类(java.io.FileWriter)可将字符写入文件。FileWriter 的工作原理与 FileOutputStream 非常相似,只是 FileOutputStream 是基于字节的,而 FileWriter 是基于字符的。换句话说,FileWriter 的目的是写入文本。一个字符可能对应一个或多个字节,具体取决于使用的字符编码方案。
注意,FileWriter 类也是 Writer 类的子类。
以下是一个简单的 FileWriter 示例:
package com.hxstrive.java_io; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; public class FileWriterExample { public static void main(String[] args) throws IOException { // 利用 try-with-resources,自动释放资源 try(Writer writer = new FileWriter("output.txt")) { writer.write('A'); // 写入字符 writer.write("Hello, World!"); // 写入字符串 } } }
上述示例,首先创建了一个 FileWriter,然后向文件中写入字符“A”以及字符串“Hello, World!” 。注意,FileWriter 还有其他构造函数,可让您以不同方式指定要写入的文件。如下:
FileWriter(File file)
FileWriter(File file, boolean append) 如果 append 为 true,则以追加的模式打开文件。
FileWriter(FileDescriptor fd)
FileWriter(String fileName) 根据传递的文件名,打开文件。
FileWriter(String fileName, boolean append) 如果 append 为 true,则以追加的模式打开文件。
创建 FileWriter 时,您可以决定是否要覆盖任何同名的已经存在的文件,或者是否将新内容追加到任何现有文件中。这可以通过选择使用不同的 FileWriter 构造函数来决定。
当 FileWriter 构造函数只有一个参数,即文件名,它将覆盖任何现有文件:
Writer fileWriter = new FileWriter("c:\\data\\output.txt");
当 FileWriter 的构造函数有 2 个参数,第一个参数为文件名,第二个参数为一个布尔值。布尔值表示是追加还是覆盖现有文件。下面是两个 Java FileWriter 示例:
Writer fileWriter = new FileWriter("c:\\data\\output.txt", true); // 追加到文件 Writer fileWriter = new FileWriter("c:\\data\\output.txt", false); // 覆盖文件
FileWriter 默认会采用应用程序运行所在计算机的默认字符编码,将字符编码(默认字符编码)为字节并写入文件。但这可能并非你所期望的,而且你无法改变这一默认设置,因为 FileWriter 不允许修改字符。
如果你想指定其他字符编码,就别用 FileWriter 了,可在 FileOutputStream 上搭配使用 OutputStreamWriter。借助 OutputStreamWriter,你能自行指定在将字节写入底层文件时所用的字符编码。例如:
public static void main(String[] args) throws Exception { try(Writer writer = new OutputStreamWriter(new FileOutputStream("output.txt"), "GBK")) { writer.write("你好"); } }
FileWriter 的 write(int) 方法将 int 的低 16 位作为一个字符写入 FileWriter 所连接的目标。例如:
FileWriter fileWriter = new FileWriter("output.txt"); fileWriter.write('A');
FileWriter 还有一个 write(char[]) 方法,可将字符数组写入 FileWriter 所连接的目标。write(char[]) 方法返回实际写入 FileWriter 的字符数。例如:
FileWriter fileWriter = new FileWriter("output.txt"); char[] chars = new char[]{'A','B','C','D','E'}; // 字符数组 fileWriter.write(chars);
注意,向 FileWriter 写入字符数组要比一次写入一个字符快,而且速度提升非常明显,最高可提升 10 倍或更多。因此,建议尽可能使用 write(char[]) 方法。
具体的速度提升取决于运行 Java 代码的计算机的底层操作系统和硬件。速度提升取决于内存速度、硬盘速度和缓冲区大小等。
使用 BufferedWriter 对 FileWriter 进行封装,即可实现透明缓冲。所有写入 BufferedWriter 的字节,都会先暂存于其内部字节数组中。当缓冲区被填满时,其中内容将一次性刷新至底层 FileWriter ,完成数据写入 。
下面是一个用 BufferedWriter 封装 FileWriter 的示例:
int bufferSize = 8 * 1024; Writer writer = new BufferedWriter( new FileWriter("c:\\data\\output-file.txt"), bufferSize);
FileWriter 的 flush() 方法能够将写入 FileWriter 的所有数据刷新到其对应的底层文件里。即便 Java 代码已把数据写入 FileWriter,这些数据可能仍暂存在操作系统内存的某处。调用 flush() 方法,能确保所有缓冲数据都被刷新(即写入)到磁盘。
以下是调用 flush() 方法刷新写入 Java FileWriter 数据的示例:
fileWriter.flush();
当你完成向 FileWriter 写入字符后,应记得关闭它。关闭 FileWriter 只需要调用 close() 方法。如下:
fileWriter.close();
当然,你还可以使用 Java7 中引入的 try-with-resources 结构,自动关闭资源,如下:
try(FileWriter fileWriter = new FileWriter("filewriter.txt")){ fileWriter.write("data 1"); }
注意,上述示例没有明确调用 close() 方法,完全由 try-with-resources 结构帮我们去调用 close() 方法。