Java FileReader和FileWriter的用法(附带实例)
Java 程序中,文件读取器(FileReader)用于以字符的形式来读取文件。

图 1 文件读取器
如上图所示,FileReader 类更多被用来读取文本类型的文件,比如 .txt 文件、.java 文件、.html 文件、.ini 文件等。FileReader 类的父类是 Reader 类。
FileReader 与 FileInputStream 的功能非常相似,差别只在于前者以字符、后者以字节为粒度。简单地说,字符与字节的差别就在于每次读取的位数,字节一次读取 8 位(byte类型),而字符则一次读取 16 位(char 类型)。
从信息容量上看差别很大,8 位能表示 256 种数值,而 16 位能表示 65536 种数值。也就是说一字节所能表示的符号集合非常有限,仅包括数字、英文大小写字母、常见标点符号以及其他符号,对应于 ASCII 编码。而一个字符能表示的符号集合则大得多,此时就有可能将常见的中文文字都包括进来。
我们在 D 盘下创建一个 test.txt 文件,内容如下图所示,同时以 UTF-8 编码保存。

图 2 以 UTF-8 编码保存文件
此时我们仍然通过 FileInputStream 来读取文件内容,如下面的实例代码所示,看看输出什么内容。
可以通过下面的 4 种方式来创建 FileReader 对象:
为了能正确读取出中文,我们可以使用 FileReader 来读取文件,如下面的实例程序所示:

图 3 文件写入器
FileWriter 类的父类是 Writer 类。共有 8 种构造方法可以用来创建 FileWriter 对象:
下面我们来看看程序中如何使用 write() 方法写入字符数据:

图 4 文件内容
注意,必须要在 finally 块中关闭文件写入器。
我们对上面的例子稍加改动,通过“FileWriter("D:/test.txt",true)”来创建文件写入器对象,它将以追加的方式写入数据:

图 5 文件内容

图 1 文件读取器
如上图所示,FileReader 类更多被用来读取文本类型的文件,比如 .txt 文件、.java 文件、.html 文件、.ini 文件等。FileReader 类的父类是 Reader 类。
FileReader 与 FileInputStream 的功能非常相似,差别只在于前者以字符、后者以字节为粒度。简单地说,字符与字节的差别就在于每次读取的位数,字节一次读取 8 位(byte类型),而字符则一次读取 16 位(char 类型)。
从信息容量上看差别很大,8 位能表示 256 种数值,而 16 位能表示 65536 种数值。也就是说一字节所能表示的符号集合非常有限,仅包括数字、英文大小写字母、常见标点符号以及其他符号,对应于 ASCII 编码。而一个字符能表示的符号集合则大得多,此时就有可能将常见的中文文字都包括进来。
我们在 D 盘下创建一个 test.txt 文件,内容如下图所示,同时以 UTF-8 编码保存。

图 2 以 UTF-8 编码保存文件
此时我们仍然通过 FileInputStream 来读取文件内容,如下面的实例代码所示,看看输出什么内容。
public class IOtest { public static void main(String[] args) throws IOException { FileInputStream fis = null; try { fis = new FileInputStream("D:/test.txt"); for (;;) { int value = fis.read(); if (value == -1) break; System.out.print((char) value); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) fis.close(); } } }输出如下:
test123 ?????????è??可以看到英文和数字都能正确读取,而中文则出现了一堆问号,这些就是乱码。
可以通过下面的 4 种方式来创建 FileReader 对象:
FileReader(String fileName) FileReader(File file) FileReader(String fileName, Charset charset) FileReader(File file, Charset charset)文件路径可以传入 String 类型或 File 类型,另一个 Charset 类型的参数表示编码类型,如果不传入则会使用默认编码。
为了能正确读取出中文,我们可以使用 FileReader 来读取文件,如下面的实例程序所示:
public class IOtest { public static void main(String[] args) throws IOException { FileReader fr = null; try { fr = new FileReader("D:/test.txt", StandardCharsets.UTF_8); int value; while ((value = fr.read()) != -1) { System.out.print((char) value); } } catch (Exception e) { e.printStackTrace(); } finally { fr.close(); } } }由于我们使用的是 UTF-8 编码来保存文件,因此在创建 FileReader 对象时编码类型要指定为 StandardCharsets.UTF_8,否则会默认使用 GBK 编码,从而产生乱码问题。关于读取操作的代码我们已经很熟悉了,这里不再详细讲解。
Java FileWriter文件写入器
文件写入器(FileWriter)用于以字符形式将数据写入文件,如下图所示:
图 3 文件写入器
FileWriter 类的父类是 Writer 类。共有 8 种构造方法可以用来创建 FileWriter 对象:
FileWriter(String fileName) FileWriter(String fileName, boolean append) FileWriter(String fileName, Charset charset) FileWriter(String fileName, Charset charset, boolean append) FileWriter(File file) FileWriter(File file, boolean append) FileWriter(File file, Charset charset) FileWriter(File file, Charset charset, boolean append)
- 其中文件路径是必备参数,文件路径可以是 String 类型或 File 类型。另外还有两个可选参数:
- boolean 类型值表示是否以追加方式写入文件,如果该值为 true 表示写入的内容追加到文件末尾,如果为 false 则表示清空原来文件的内容从头开始写入;
- Charset 类型参数表示用什么编码写入文件,读取时必须与这里写入的编码一致,否则会产生乱码。
下面我们来看看程序中如何使用 write() 方法写入字符数据:
public class IOtest { public static void main(String[] args) throws IOException { FileWriter fw = null; try { fw = new FileWriter("D:/test.txt"); fw.write('你'); fw.write('好'); fw.write("程序员"); fw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { fw.close(); } } }先创建 FileWriter 对象,然后调用 write() 方法将“你”“好”两个字符和“程序员”字符串写入文件,结果如下图所示。

图 4 文件内容
注意,必须要在 finally 块中关闭文件写入器。
我们对上面的例子稍加改动,通过“FileWriter("D:/test.txt",true)”来创建文件写入器对象,它将以追加的方式写入数据:
public class IOtest { public static void main(String[] args) throws IOException { FileWriter fw = null; try { fw = new FileWriter("D:/test.txt", true); fw.write('你'); fw.write('好'); fw.write("程序员"); fw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { fw.close(); } } }此时如果我们执行三次程序,将写入三次“你好程序员”,最终结果如下图所示。

图 5 文件内容