• Reader InputStreamReader FileReader and BufferedReader
  • Writer OutputStreamWriter FileWriter and BufferedWriter
  • Character Encoding and Charset
    • BufferedReader
    • BufferedWriter
    • 本篇博文主要介绍 如何使用java.io包中提供的类读取和写入文本(或字符)文件


      Reader, InputStreamReader, FileReader and BufferedReader

      Reader是读取字符流的抽象类。 它实现以下基本方法:

      • read(): reads a single character.
      • read(char[]): reads an array of characters.
      • skip(long): skips some characters.
      • close(): closes the stream.

      InputStreamReader是从字节流到字符流的桥梁。 它使用指定的字符集将字节转换为字符。 字符集可以是操作系统的默认字符编码,也可以在创建InputStreamReader时显式指定。

      FileReader是使用操作系统的默认字符编码读取文本文件的便捷类。

      BufferedReader从字符流中读取文本(字符被缓冲以避免从基础流中经常读取),并提供了一种方便的阅读文本行readLine()的方法。

      我们来看下Reader的继承关系


      Writer, OutputStreamWriter, FileWriter and BufferedWriter

      Writer是写入字符流的抽象类。 它实现以下基本方法:

      • write(int): writes a single character.
      • write(char[]): writes an array of characters.
      • write(String): writes a string.
      • close(): closes the stream.

      OutputStreamWriter是从字节流到字符流的桥梁。 使用指定的字符集将字符编码为字节。 字符集可以是操作系统的默认字符编码,也可以在创建OutputStreamWriter时显式指定。

      FileWriter是使用操作系统的默认字符编码编写文本文件的便捷类。

      BufferedWriter有效地将文本写入字符流(字符,数组和字符串被缓冲以避免频繁写入底层流),并为 写入行分隔符newLine() 提供了一种方便的方法。


      Character Encoding and Charset

      当构建reader 或者 writer 对象时,使用操作系统的默认字符编码

          FileReader fileReader = new FileReader("myFile.txt");
          FileWriter fileWriter = new FileWriter("YourFile.txt");

      所以,如果我们要使用特定的字符集,请改用InputStreamReader或OutputStreamWriter

      InputStreamReader reader = new InputStreamReader(
                          new FileInputStream("MyFile.txt"), "UTF-16");

      这将创建一个具有Unicode字符编码UTF-16的InputStreamReader

      构造具有UTF-8编码OutputStreamWriter

      OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("MyFile.txt"), "UTF-8");
      

      如果我们想使用BufferedReader,只需将InputStreamReader包装在其中,例如:

      BufferedReader bufferedReader = new BufferedReader(
                      new InputStreamReader(new FileInputStream("MyFile.txt"), "UTF-8"));

      同样的 BufferedWriter 如下

      OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("MyFile.txt"), "UTF-16");
      BufferedWriter bufferedWriter = new BufferedWriter(osw);

      BufferedReader

      示例一: 从文件MyFile.txt读取单个字符,并将所有字符打印到输出控制台:

      @Test
          public void test() {
              FileReader fileReader = null;
              try {
                  fileReader = new FileReader(new File("D:/xgj.txt"));
                  int character;
                  while ((character = fileReader.read()) != -1) {
                      System.out.println((char) character);
                  // close stream
                  fileReader.close();
              } catch (IOException e) {
                  e.printStackTrace();
      

      示例二 读取文本文件,假设编码为UTF-8:

      @Test
          public void test() {
              InputStreamReader in;
              try {
                  in = new InputStreamReader(new FileInputStream(new File("D:/xgj.txt")), "UTF-8");
                  int character;
                  while ((character = in.read()) != -1) {
                      System.out.println((char) character);
                  // close stream
                  in.close();
              } catch (UnsupportedEncodingException e) {
                  e.printStackTrace();
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
      

      示例三 使用BufferedReader逐行读取文本文件(这是最有效和首选的方式):

      @Test
          public void test() {
              BufferedReader bufferedReader;
              try {
                  bufferedReader = new BufferedReader(new FileReader(new File("D:/xgj.txt")));
                  String line;
                  while ((line = bufferedReader.readLine()) != null) {
                      System.out.println(line);
                  // close stream
                  bufferedReader.close();
              } catch (IOException e) {
                  e.printStackTrace();
      

      BufferedWriter

      使用FileWriter将两个单词“Hello World”和“Good Bye!”写入名为MyFile.txt的文件:

      @Test
          public void test() {
              FileWriter fileWriter;
              try {
                  // If the second argument is true, then bytes will be written to the
                  // end of the file rather than the beginning.
                  fileWriter = new FileWriter(new File("D:/MyFile.txt"), true);
                  fileWriter.write("Hello World");
                  fileWriter.write("\r\n"); // write new line
                  fileWriter.write("Good Bye!");
                  // close stream
                  fileWriter.close();
              } catch (IOException e) {
                  e.printStackTrace();
      

      请注意,FileWriter默认使用操作系统的默认字符编码。 如果文件不存在将创建一个新的文件,存在则覆盖现有的。
      如果要将文本附加到现有文件,请将FileWriter类的构造函数第二个入参true.

      FileWriter writer = new FileWriter("MyFile.txt", true);

      示例二 使用一个包含FileWriter的BufferedWriter 来将文本附加到现有文件中:

      这是写入文本文件的首选方法,因为BufferedWriter 提供了写入字符流的有效方式。

      @Test
          public void test() {
              BufferedWriter bufferedWriter;
              try {
                  bufferedWriter = new BufferedWriter(new FileWriter("D:/Myfile.txt", true));
                  bufferedWriter.write("Hello World");
                  bufferedWriter.newLine(); // 分隔符
                  bufferedWriter.write("See You Again!");
                  // close stream
                  bufferedWriter.close();
              } catch (IOException e) {
                  e.printStackTrace();
      

      以下示例在写入文件时指定特定字符编码(UTF-8):

      @Test
          public void test() {
              try {
                  FileOutputStream outputStream = new FileOutputStream("D:/MyFile.txt");
                  OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
                  BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
                  bufferedWriter.write("Hello");
                  bufferedWriter.newLine();
                  bufferedWriter.write("I/O");
                  // close stream
                  bufferedWriter.close();
              } catch (IOException e) {
                  e.printStackTrace();
      

      注意:
      从Java 7开始,我们可以使用try-with-resources语句简化打开和关闭读写器的代码。 例如:

      try (FileReader reader = new FileReader("MyFile.txt")) {
          int character;
          while ((character = reader.read()) != -1) {
              System.out.print((char) character);
      } catch (IOException e) {
          e.printStackTrace();