字符流是针对字符数据的特点进行过优化的流,因而提供了一些对面向字符的有用特性,字符流的目标或者源通常是文本文件。Reader和Writer是java.io包中所有字符流的父类。由于它们都是抽象类,所以应该使用它们的子类来创建实体对象,利用对象来处理相关的读写操作。Reader和Writer的子类又可以分为两大类:一类用来从数据源读入数据或往目的地写入数据,另一类对数据执行某种处理。
面向字符的输入流都是Reader的子类,它的类层次结构如图所示:
类名 | 功能描述 |
---|---|
CharArrayReader | 从字符数组读取的输入流 |
BufferedReader | 缓冲输入字符流 |
PipedReader | 输入管道 |
InputStreamReader | 将字节转换到字符的输入流 |
FilterReader | 过滤输入流 |
StringReader | 从字符串读取的输入流 |
LineNumberReader | 为输入数据附加行号 |
PushbackReader | 返回一个字符并把此字节放回输入流 |
FileReader | 从文件读取的输入 |
来看一个例子,该例子把一个文件的字符全部读取到控制台。
public class Demo2 {
public static void main(String[] args) throws IOException {
//文件路径字符串
String filePath="C:\\Users\\xiake\\Desktop\\文本.txt";
//在创建输入流对象的同时设置字符编码
InputStreamReader isr=new InputStreamReader(new FileInputStream(filePath),"gbk");
char[] ch=new char[1024];
//读取字符到char数组中
int num=isr.read(ch);
System.out.println("一共读取了"+num+"个字符");
String str=String.valueOf(ch,0,num);
System.out.println(str);
}
}
运行结果:
一共读取了22个字符
ABCDEFG
HIJKLMN
我爱祖国
需要注意的是,Java把一个汉字或英文字母作为一个字符对待,回车或换行作为两个字符对待。
还可以把一个文件的字符读取出来,存储到另一个文件中。
public class Demo2 {
public static void main(String[] args) throws IOException {
//文件路径字符串
String inFilePath="C:\\Users\\xiake\\Desktop\\文本.txt";
String outFilePath="C:\\Users\\xiake\\Desktop\\文本1.txt";
//在创建输入流对象的同时设置字符编码
InputStreamReader isr=new InputStreamReader(new FileInputStream(inFilePath),"gbk");
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream(outFilePath), "gbk");
//得到源文件的字符长度
Long fileSize=new File(inFilePath).length();
char[] ch=new char[fileSize.intValue()];
//读取字符到char数组中
//一次性读取
int num=isr.read(ch);
//一次性存储
osw.write(ch);
System.out.println("一共读取了"+num+"个字符");
String str=String.valueOf(ch,0,num);
System.out.println(str);
//最后,关闭流对象
if(br!=null){
br.close();
}
if(bw!=null){
bw.close();
}
}}
使用BufferedReader和BufferedWriter缓冲流包装字符输入输出流,一次可以读取一行。
public class Demo2 {
public static void main(String[] args) throws IOException {
//文件路径字符串
String inFilePath="C:\\Users\\xiake\\Desktop\\文本.txt";
String outFilePath="C:\\Users\\xiake\\Desktop\\文本1.txt";
//在创建输入流对象的同时设置字符编码
InputStreamReader isr=new InputStreamReader(new FileInputStream(inFilePath),"gbk");
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream(outFilePath), "gbk");
BufferedReader br=new BufferedReader(isr);
BufferedWriter bw=new BufferedWriter(osw);
String data=null;
//读取一行字符
while((data=br.readLine())!=null){
//写入
bw.write(data);
//写入一个换行
bw.newLine();
}
//最后,关闭流对象
if(br!=null){
br.close();
}
if(bw!=null){
bw.close();
}
}
}
需要注意的是,执行read()方法或write()方法,可能由于IO错误,都会抛出IOException异常。需要处理异常或者抛出异常,我这里是选择的是抛出异常,不处理。