当使用字节流读取文件时,可能会有一个问题,就是遇到中文字符时,可能不会显示完整的字符,那是因为一个中文字符可能占用多个字节存储,所以Java提供了字符流类,以字符为单位读写数据,专门用于处理文本文件。
字符流=字节流+编码表
汉字在存储的时候,不管是GBK还是UTF-8,第一个字节都是负数
注意:使用什么字符集编码,就使用什么字符集解码
Java.io.Reader抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中,它定义了字符输入流的基本共性功能方法:
Reader有很多子类,以最简单常用的FileReader为例:FileReader类是读取字符文件的便利类,构造时使用系统默认的字符编码和默认字节缓冲区
FileReader(File file):创建一个FileReader对象,给定要读取的File对象
File file=new File("D:\\aaa\\helloworld.txt");
FileReader fr=new FileReader(file);
FileReader(String fileName):创建一个FileReader对象,给定要读取的文件的名称
FileReader fr=new FileReader("D:\\aaa\\helloworld.txt");
当你创建一个流对象时,必须传入一个文件路径,与字节流类似
read():读取字符,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1
File file=new File("D:\\aaa\\helloworld.txt");//文件中的内容是:我是中国人
FileReader fr=new FileReader(file);
int b;
while((b=fr.read())!=-1) {
System.out.print((char)b);
}
fr.close();
//输出:我是中国人
read(char[] cbuf):使用字符数组读取,每次读取b的长度个字符到数组中,返回读取到的有效字符个数,读取到末尾时,返回-1
File file=new File("D:\\aaa\\helloworld.txt");
FileReader fr=new FileReader(file);
int len;
char[] c=new char[2];
while((len=fr.read(c))!=-1) {
System.out.println(new String(c));
}
fr.close();
/*输出:我是
中国
人国
*/
最后一次输出了“人国”是由于最后一次读取时,只读取一个字符“人”,数组中上次读取的数据没有被完全替换,所以要通过len获取有效的字符,改进代码如下:
File file=new File("D:\\aaa\\helloworld.txt");
FileReader fr=new FileReader(file);
int len;
char[] c=new char[2];
while((len=fr.read(c))!=-1) {
System.out.println(new String(c,0,len));
}
fr.close();
/*输出:我是
中国
人
*/
Java.io.Writer抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地,它定义了字符输出流的基本共性功能方法:
Writer有很多子类,以最简单常用的FileWriter为例:FileWriter类是写出字符到文件的便利类,构造时使用系统默认的字符编码和默认字节缓冲区
FileWriter(File file):创建一个FileWriter对象,给定要写入的file对象
File file=new File("D:\\aaa\\helloworld.txt");
FileWriter fw=new FileWriter(file);
FileWriter(String fileName):创建一个FileWriter对象,给定要写入的文件的名称
FileWriter fw=new FileWriter("D:\\aaa\\helloworld.txt");
当你创建一个流对象时,必须传入一个文件路径,与字节流类似
write(int b):写出字符,每次可以写出一个字符数据
File file=new File("D:\\aaa\\helloworld.txt");
FileWriter fw=new FileWriter(file);
fw.write(19999);//中文编码表中19999对应一个汉字
fw.write(65);
fw.write('B');
fw.write('C');
fw.write('D');
fw.close();
//文件中写入:丢ABCD
注意:如果未调用close方法关闭资源,数据只是保存到缓冲区,并未保存到文件
write(char[] cbuf)和write(char[] cbuf,int off,int len):写出字符数组,每次可以写出字符数组中的数据
File file=new File("D:\\aaa\\helloworld.txt");
FileWriter fw=new FileWriter(file);
char[] c="我是中国人".toCharArray();
fw.write(c);//文件中写入:我是中国人
fw.write(c,2,3);//文件中写入:中国人
fw.close();
write(String str)和write(String str,int off,int len):写出字符串,每次可以写出字符串中的数据,更为方便
File file=new File("D:\\aaa\\helloworld.txt");
FileWriter fw=new FileWriter(file);
String s="我是中国人";
fw.write(s);//文件中写入:我是中国人
fw.write(s, 2, 3);//文件中写入:中国人
fw.close();
续写和换行:操作类似于FileOutStream
File file=new File("D:\\aaa\\helloworld.txt");
FileWriter fw1=new FileWriter(file);
String s="你好";
fw1.write(s);
fw1.close();
FileWriter fw2=new FileWriter(file,true);//续写
fw2.write("我是中国人");
fw2.write("\r\n");//写入换行
fw2.write("加油");
fw2.close();
/*文件中写入了:你好我是中国人
加油
*/
因为内置缓冲区的原因,如果不关闭输出流,就无法写出字符到文件中,但是关闭的流对象,是无法继续写出数据的,如果我们既想写出数据到文件中,又想继续使用流,就需要使用flush方法
File file=new File("D:\\aaa\\helloworld.txt");
FileWriter fw1=new FileWriter(file);
String s="你好";
fw1.write(s);
fw1.flush();//刷新后,文件中写入“你好”
fw1.write("谢谢");
fw1.close();//调用close方法,文件中写入“谢谢”
注意:即便是flush方法写出了数据,操作的最后还是要调用close方法,释放系统资源