在前面讲解了基础的文件字节输入输出流之后,我们将进行更深层次的文件字符输入输出流以及缓冲流。其实在I/O流这一块,有着很多流,我会做关于每个流的文章详细介绍。
一、文件字符输入输出流
为什么要使用文件字符输入输出流?前面已经讲过文件字节输入输出流,其已经可以对文件写入或者读取信息。但由于其单位是字节,通过字节数组进行读写数据,因此不能很好的操作Unicode字符,就拿汉字来说,一个汉字占两位字节,如果操作不当就回出现乱码的现象。
因此我们引入了文件字符输入输出流。
与FileInputStream、FileOutputStream字节流相对应的是FileReader、FileWriter字符流。FileReader和FileWriter分别是Reader和Writer的子类。它们的构造方法如下:
FileReader(String filename);
FileReader(File filename);
FileReader(String filename,boolean append);
FileWriter(String filename);
FileWriter(File filename);
FileWriter(File filename,boolean append);
注意:字符输入输出流使用read和writer方法对字符数组进行读写数据。所以其基本单位是字符。
请看示例:我现通过文件字符输入输出流将read.txt文件中的内容转移到writer.txt文件中。
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
public class Main{
public static void main(String[] args) {
File readfile = new File("E:\\Java\\read.txt");
File writerfile = new File("E:\\Java\\writer.txt");
char arr[] = new char[100];
try {
Writer writer = new FileWriter(writerfile,true);
Reader read = new FileReader(readfile);
int n = -1;
while ((n = read.read(arr))!=-1) {
writer.write(arr,0,n);
}
writer.flush();
writer.close();
System.out.println("成功将read.txt文件中的内容写入writer.txt文件中!");
} catch (IOException e) {
// TODO: handle exception
System.out.println(e);
}
}
}
要点: 关于Writer流,我们详细介绍一下。原理:writer方法将数据首先写入到缓存区,每当缓存区溢出时,缓存区的内容被自动写入到目的地,如果关闭流,缓存区的内容会立刻被写入到目的地。流调用flush()方法可以立即冲洗当前缓存区,也就是将当前缓存区的内容写入到目的地。
二、缓存流
为了解决输入输出流的更深层次的问题,我们必须要引入缓存流。那什么是更深层次的问题呢?就比如说,在前面所讲到的输入输出流就只能把读取到的数据放进另一个文件中的一行,可想,在一列表的数据中,如果将数据都写成一行,会是多么麻烦不好看。所以为了增强读写文件的能力,我们引入BufferedReader和BufferedWriter类创建缓冲输入、输出流的对象。
这里需要注意的是,BufferedReader流和BufferedWriter流的源和目的地必须是字符输入输出流。
构造方法:
BufferedReader(Reader in);
BufferedWriter(Writer out);
BufferedReader流能够读取文本行,方法是readLine()。
BufferedWriter流能够写入文本,方法是write(String s,int off,int len)。
我们可以使用缓冲输入流调用readLine()方法读取文件信息。然后使用缓冲输出流调用write(String s,int off,int len)方法把字符串s写入到目的地中,参数off是字符串s的开始处偏移量,len是写入的字符数量。
值得一提的是,BufferedWriter流有一个独特的向文件写入一个回车符的方法:
newLine();
要点: 我们可以把BufferedReader和BufferedWriter称为上层流,把它们指向的字符流称为底层流。Java采用缓存技术将上层流和底层流连接。底层字符输入流首先将数据读入缓存,BufferedReader流再从缓存读取数据;BufferedWriter流将数据写入缓存,底层字符输出流会不断地将缓存中的数据写入目的地。当BufferedWriter流调用flush()刷新缓存或调用close()方法关闭时,即使缓存没有溢出,底层流也会立刻将缓存的内容写入目的地。
注:在关闭输出流时首先要关闭缓存输出流再关闭缓存输出流所指向的流。即先关闭上层流再关闭下层流。
缓存流示例:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
public class Main{
public static void main(String[] args) {
File read = new File("E:\\Java\\read.txt");
File writer = new File("E:\\Java\\writer.txt");
try {
Writer out = new FileWriter(writer);
BufferedWriter bufferedWriter = new BufferedWriter(out);
Reader in = new FileReader(read);
BufferedReader bufferedReader = new BufferedReader(in);
String str = null;
while ((str=bufferedReader.readLine())!=null) {
bufferedWriter.write(str);
bufferedWriter.newLine();
}
bufferedWriter.flush();
out.close();
System.out.println("数据成功写入!");
} catch (IOException e) {
// TODO: handle exception
System.out.println(e);
}
}
}