使用FileReader和FileWriter实现对文本文件的复制操作
首先我们先给出步骤:
- 创建File对象,指明读入和写出的文件
- 创建输入流(FileReader)对象和输出流(FileWriter)对象
- 数据的读入和写出操作
- 关闭流资源
- 流资源的关闭操作要写在finally代码块中,并且我们的流资源的关闭操作本身也有一个编译期异常,这个时候我们给流资源的关闭也加一个try — catch操作
- 并且如果我们前面创建流资源之前程序就出现了异常的话,这个时候我们如果后面进行流资源的关闭这个时候就会出现空指针异常 — 所以这个时候我们就要先使用一个if语句判断一下这个流对象是否为空,如果这个时候流资源为空,那么这个时候我们没有创建流资源这个时候自然也就不需要使用流的关闭操作了
这里我们通过一个例子来理解FileReader和FileWriter对文本文件的复制操作
package IO流.FileWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.File;
public class Demo2 {
public static void main(String[] args) {
FileReader fileReader = null;
FileWriter fileWriter = null;
/*
创建File类的对象,指明读入和写出的文件 --- 也就是指明输入和输出的终点
*/
File srcFile = new File("hello.txt");
File destFile = new File("hello2.txt");
/*
由于这个时候我们有关流的很多操作都会报出异常,这个时候我们又因为我们的关闭流的操作必须要执行
因为我们的输入输出流其实是一种物理连接,像这样的物理连接我们的jvm垃圾回收机制是不能将其回收的
这个时候就要我们进行手动回收 --- 但是又由于这个时候前面可能会发生异常,这个时候如果在创建流对象之后,
关闭流之前发生了异常,这个时候这个流关闭的操作就不会执行 --- 所以我们就最好将流的关闭操作写到finally
代码块中
*/
try{
/*
创建输入和输出流的对象
*/
fileReader = new FileReader(srcFile);
fileWriter = new FileWriter(destFile);
/*
创建缓冲数组
*/
char [] chars = new char[5];
/*
创建一个临时变量用来接收read()方法的返回值 --- 后面用于读取文件时的准确性
*/
int len = 0;
while ((len = fileReader.read(chars)) != -1) {
/*
这个时候我们使用的是一个由三个参数的write()方法
这个read(chars , 0 , led)方法的实际意义是: 这个第一个参数就是每次将读取到
的数据存储到这个chars数组中,第二个参数表示从这个chars数组的第0个索引位置开始存
,第三个参数表示每次读取到这个数组中的元素的个数
*/
fileWriter.write(chars,0,len);
}
}catch(IOException e){
e.printStackTrace();
}finally{
/*
我们将流的关闭的操作放到了finally代码块中 --- 就是为了我们的流对象一定能关闭掉
*/
if(fileReader != null){
/*
如果前面我们还没有进行创建流对象的时候就出现了异常,这个时候流对象没有创建,这个时候我们的
这个流对象对应的引用为初始值null,这个时候如果我们调用这个null对应的引用去调用这个流的关闭操作
这个时候就会出现空指针异常 ---- 这个时候我们为了避免出现空指针异常,这个时候我们要进行一个if语句
的判断,如果流对象对应的引用不为null,这个时候我们才执行流的关闭操作
*/
try{
fileReader.close();
}catch(IOException e){
e.printStackTrace();
}
}
/*
这里和上面一样都是为了避免空指针异常的发生
*/
if(fileWriter != null){
try{
fileWriter.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
}
- 这个程序其实就是将我们的一个文件中的内容以字符为单位读出, 然后存放到一个char[]中 ,然后再以字符为单位将char[]中的我们读入的数据写入到我们的另一个文件中
注意: 最后的两个流对象的关闭操作我们写到并列的两个try代码块中就可以,不用将一个流的关闭操作写到另一个流的关闭操作对应的finally代码块中
- 因为就算我们前一个流的关闭操作的过程中如果出现了异常,这个时候我们已经使用了try – catch对这个异常进行了处理,这个时候即使我们的关闭流的操作出现了IOException,那么我们对应的catch语句会将我们的异常兑现进行捕捉,这个时候异常对象没有抛出到虚拟机中去,这个时候程序也就不会终止运行,这个时候我们的后面的流的关闭操作还是可以正常进行