学科分类
目录
Java基础

字符流操作文件

在程序开发中,经常需要对文本文件的内容进行读取,如果想从文件中直接读取字符便可以使用字符输入流FileReader,通过此流可以从文件中读取一个或一组字符。接下来通过一个案例来学习如何使用FileReader以字符的形式读取文件中的内容。

首先在项目当前目录下新建文本文件“reader.txt”并在其中输入字符“好好学习,天天向上!”,然后创建一个使用字符输入流FileReader读取文件中字符的类,如文件1所示。

文件1 Example07.java

 1    import java.io.*;
 2    public class Example07 {
 3        public static void main(String[] args) throws Exception {
 4             // 创建FileReader对象,并指定需要读取的文件
 5            FileReader fileReader = new FileReader("reader.txt");
 6            // 定义一个int类型的变量len,其初始化值为0
 7            int len = 0;
 8            // 通过循环来判断是否读取到了文件末尾
 9            while ((len = fileReader.read()) != -1) {
 10                // 输出读取到的字符
 11                System.out.print((char)len);
 12            }
 13            // 关闭流
 14            fileReader.close();
 15        }
 16    }

运行结果如图1所示。

图1 运行结果

文件1实现了读取文件字符的功能。首先创建一个FileReader对象来读取指定文件内容,然后通过while循环每次从文件中读取一个字符并打印,这样便实现了FileReader读文件字符的操作。由于字符输入流的read()方法返回的是int类型的值,如果想获得字符就需要进行强制类型转换,所以输出语句中将变量len强转为了char类型。

文件1讲解了如何使用FileReader读取文件中的字符,如果要向文件中写入字符就需要使用FileWriter类,该类是Writer的一个子类。接下来通过一个案例来学习如何使用FileWriter将字符写入文件,如文件2所示。

文件2 Example08.java

 1    import java.io.*;
 2    public class Example08 {
 3        public static void main(String[] args) throws Exception {
 4            // 创建字符输出流对象,并指定输出文件
 5            FileWriter fileWriter = new FileWriter("writer.txt");
 6            // 将定义的字符写入文件
 7            fileWriter.write("轻轻的我走了,\r\n");
 8            fileWriter.write("正如我轻轻的来;\r\n");
 9            fileWriter.write("我轻轻的招手,\r\n");
 10            fileWriter.write("作别西天的云彩。\r\n");
 11            // 关闭流
 12            fileWriter.close();
 13        }
 14    }

程序运行结束后,会在当前目录下生成一个名称为“writer.txt”的文件,打开此文件会看到如图2所示的内容。

图2 writer.txt

FileWriter同FileOutputStream一样,如果指定的文件不存在,就会先创建文件,再写入数据,如果文件存在,则会首先清空文件中的内容,再进行写入。如果想在文件末尾追加数据,同样需要调用重载的构造方法,现将文件2中的第5行代码进行如下修改:

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

修改后,再次运行程序,即可实现在文件中追加内容的效果。

上面两个文件示例通过字符流的形式完成了对文件内容的读写操作,但也是逐个字符进行读写,这样也需要频繁的操作文件,效率仍非常低。这里也可以使用提供的字符流缓冲区(类似于字节流缓冲区)进行读写操作,来提高执行效率。

接下来,通过一个案例来学习如何使用字符流的缓冲区实现文件的拷贝,如文件3所示。

文件3 Example09.java

 1    import java.io.*;
 2    public class Example09 {
 3        public static void main(String[] args) throws Exception {
 4            // 创建FileReader对象,并指定需要读取的文件
 5            FileReader fileReader = new FileReader("reader.txt");
 6            // 创建FileWriter对象,并指定写入数据的目标文件
 7            FileWriter fileWriter = new FileWriter("writer.txt");
 8            // 定义一个int类型的变量len,其初始化值为0
 9            int len = 0;
 10            // 定义一个长度为1024的字符数组
 11            char[] buff = new char[1024];
 12            // 通过循环来判断是否读取到了文件末尾
 13            while ((len = fileReader.read(buff)) != -1) {
 14                // 输出读取到的字符
 15                fileWriter.write(buff, 0, len);
 16            }
 17            // 关闭流
 18            fileReader.close();
 19            fileWriter.close();
 20        }
 21    }

文件3使用字符流缓冲区实现了文本文件reader.txt的拷贝,具体操作与字节流缓冲区实现文件拷贝类似,只是创建的缓冲区不一样,这里是使用了new char[1024]创建了一个字符缓冲区。

同样,在字节流中提供了带缓冲区功能的字节缓冲流,字符流也提供了带缓冲区的字符缓冲流,分别是BufferedReader和BufferedWriter,其中BufferedReader用于对字符输入流进行操作,BufferedWriter用于对字符输出流进行操作。需要注意的是,在BufferedReader中有一个重要的方法readLine(),该方法用于一次读取一行文本。

接下来通过一个案例来学习如何使用这两个缓冲流实现文件的拷贝,如文件4所示。

文件4 Example10.java

 1    import java.io.*;
 2    public class Example10 {
 3        public static void main(String[] args) throws Exception {
 4            // 创建一个字符输入缓冲流对象
 5            BufferedReader br = new BufferedReader(
 6                                    new FileReader("reader.txt "));
 7            // 创建一个字符输出缓冲流对象
 8            BufferedWriter bw = new BufferedWriter(
 9                                    new FileWriter("writer.txt"));
 10            // 声明一个字符串变量str
 11            String str = null;
 12            // 循环时每次读取一行文本,如果不为null(即到了文件末尾),则继续循环
 13            while ((str = br.readLine()) != null) {
 14                // 通过缓冲流对象写入文件
 15                bw.write(str);
 16                // 写入一个换行符,该方法会根据不同的操作系统生成相应的换行符
 17                bw.newLine();
 18            }
 19            // 关闭流
 20            br.close();
 21            bw.close();
 22        }
 23    }

程序运行结束后,同样会将源文件“reader.txt”中的内容拷贝到目标文件“writer.txt”中,结果如图3所示。

图3 拷贝后文件的内容

在文件4中,使用了输入输出字符缓冲流BufferedReader和BufferedWriter,并通过一个while循环实现了文本文件的拷贝。在拷贝过程中,每次循环都使用readLine()方法读取文件的一行,然后通过write()方法写入目标文件,同时使用了newLine()进行换行写入,否则读取源文件所有行内容都会追加写入目标文件一行中。其中readLine()方法会逐个读取字符,当读到回车符“\r”或换行符“\n”时会将读到的字符作为一行的内容返回。

需要注意的是,在字符缓冲流内部也使用了缓冲区,在循环中调用BufferedWriter的write()方法写入字符时,这些字符首先会被写入缓冲区,当缓冲区写满时或调用close()方法时,缓冲区中的字符才会被写入目标文件。因此在循环结束时一定要调用close()方法,否则极有可能会导致部分存在缓冲区中的数据没有被写入目标文件。

点击此处
隐藏目录