目录
字符流
1、FileReader(字符输入流)
1.1、无参的read( )方法示例
编辑
1.2、有参的read(char[ ] buffer)方法示例
2、FileWriter(字符输出流)
字符流
字符流的底层其实就是字节流,即字符流 = 字节流 + 字符集
字符流特点:
输入流:一次读一个字节,遇到中文时,一次读多个字节
输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中
使用场景:用于对于纯文本文件进行读写操作
因为 Reader 类和 Writer 类都是抽象类,不能直接创建它们的对象,得看它们的子类:FileReader(文件字符输入流)和 FileWriter(文件字节输出流)
1、FileReader(字符输入流)
FileReader的书写步骤:
1.创建字符输入流对象
构造方法 | 方法说明 |
public FileReader(File file) | 创建字符输入流关联本地文件 |
public FileReader(String pathname) | 创建字符输入流关联本地文件 |
提示:如果文件不存在,就直接报错。
2.读取数据
构造方法 | 方法说明 |
public int read() | 读取数据,若读到末尾返回-1 |
public int read(char[ ] buffer) | 读取多个数据,返回所读取数据的个数,读到末尾返回-1 |
提示:
(1)按字节进行读取。遇到中文,一次读多个字节,读取后解码,返回一个整数
(2)读到文件末尾了,read方法返回-1。
3.释放资源 方法为:public int close() 释放资源/关流
1.1、无参的read( )方法示例
用字符输入流的read( )方法读取在aaa.txt中的汉字
代码:
public static void main(String[] args) throws IOException {
/*
第一步:创建对象
public FileReader(File file) 创建字符输入流关联本地文件
public FileReader(string pathname) 创建字符输入流关联本地文件
第二步:读取数据
public int read() 读取数据,读到末尾返回-1
public int read(char[] buffer) 读取多个数据,读到末尾返回-1
第三步:释放资源
public void close() 释放资源/关流
*/
//1.创建对象并关联本地文件
FileReader fr = new FileReader("..\\javaEEStudy\\aaa.txt");
//2.读取数据 read()
//字符流的底层也是字节流,默认也是一个字节一个字节的读取的。
//如果遇到中文就会一次读取多个,GBK一次读两个字节,UTF-8一次读三个字节
//idea默认是用UTF-8;eclipse默认是用GBK
int ch;
while ((ch = fr.read()) != -1) {
System.out.print(ch);
}
//3.
fr.close();
}
运行结果:
为什么这时候的结果全是数字?这是因为空参的read( )方法,默认是一个字节一个字节的读取的,如果遇到中文就会一次读取多个。在读取之后,方法的底层会进行解码并转成十进制,最终把这个十进制作为返回值,而这个十进制的数据也表示在字符集上的数字。比如:一个英文在文件里面的二进制数据是 0110 0001,read方法进行读取,然后会把这个二进制数据进行解码并转成十进制,就是97;一个中文在文件里面的二进制数据是 11100110 10110001 10001001,read方法进行读取,然后会把这三个字节的二进制数据解码并转成十进制,就是27721。然后就会把这些十进制数赋值给变量 ch,所以输出的结果就全是数字了
如果想看到中文汉字,就是把这些十进制数据,进行强转就可以了
即:把代码中的 System.out.print(ch); 改成 System.out.print((char)ch);
改动后运行结果:
1.2、有参的read(char[ ] buffer)方法示例
用字符输入流的read(char[ ] buffer)方法读取在aaa.txt中的汉字
代码:
public static void main(String[] args) throws IOException {
/*
第一步:创建对象
public FileReader(File file) 创建字符输入流关联本地文件
public FileReader(string pathname) 创建字符输入流关联本地文件
第二步:读取数据
public int read() 读取数据,读到末尾返回-1
public int read(char[] buffer) 读取多个数据,读到末尾返回-1
第三步:释放资源
public void close() 释放资源/关流
*/
//1.创建对象并关联本地文件
FileReader fr = new FileReader("..\\javaEEStudy\\aaa.txt");
//2.读取数据
char[] chars = new char[2];
int len;
while ((len = fr.read(chars)) != -1) {
//把数组中的数据变成字符串再进行打印
System.out.println(new String(chars,0,len));
//这里的String(
//chars:要转成字符串的字符数组,
//0:表示从字符数组的0索引开始,
//len:表示字符数组中要转成字符串的字符个数)
}
//3.释放资源
fr.close();
}
运行结果:
为什么是两两一行的打印?这是因为打印时用的是System.out.println(); ,并且一次读取几个数据是根据字符数组的大小来决定的,此时字符数组定的大小是2,每读取到两个汉字就被 println() 打印出来并且换行了,所以就是两两一行的打印
为什么有些一行只有一个字并且还有空行?这是因为在文件中的每一行最后一个字后都有隐藏的换行符“\r\n”(如下图所示),比如读取第一行最后一个字“片”时,还有它后面的“\r”也被读取了,这时候就换行了,而“\r”后面的“\n”就和第二行的第一个字“想”一起被读取,“\n”也是换行,所以就换行后再打印的“想”
把 System.out.println(new String(chars,0,len)); 改成 System.out.print(new String(chars,0,len));
改动后运行结果:
read(char[ ] buffer)方法把读取数据,解码,强转三步合并了,把强转之后的字符放到数组当中。
有参的read方法 = 空参的read方法 + 强转类型转换
2、FileWriter(字符输出流)
FileWriter构造方法
构造方法 | 方法说明 |
public FileWriter(File file) | 创建字符输出流关联本地文件 |
public FileWriter(String pathname) | 创建字符输出流关联本地文件 |
public FileWriter(File file,boolean append) | 创建字符输出流关联本地文件,续写 |
public FileWriter(String pathname,boolean append) | 创建字符输出流关联本地文件,续写 |
FileWriter成员方法
成员方法 | 方法说明 |
void write(int c) | 写出一个字符 |
void write(String str) | 写出一个字符串 |
void write(String str,int off,int len) | 写出一个字符串的一部分 |
void write(char[ ] cbuf) | 写出一个字符数组 |
void write(char[ ] cbuf,int off,int len) | 写出字符数组的一部分 |
FileWriter书写步骤
1.创建字符输出流对象
参数是字符串表示的路径或者File对象都是可以的
如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的
如果文件已经存在,则会清空文件,如果不想清空可以打开续写开关
2.写数据
如果write方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符
3.释放资源
每次使用完流之后都要释放资源
代码示例:
用字符输出流的write(String str)方法往文件bbb.txt中写入汉字
public class WriterTest {
public static void main(String[] args) throws IOException {
//1.创建对象并关联本地文件
FileWriter fw = new FileWriter("..\\javaEEStudy\\bbb.txt",true);
//创建要写入数据的字符串,并且换行
String str = "\r\n这是一首简单的小情歌";
//写入数据
fw.write(str);
//关闭资源
fw.close();
}
}
运行结果:
FileWriter其他方法的写法都差不多,这里就不一一演示了
推荐:
【java基础】IO流(一):字节流的FileOutputStream(文件字节输出流)和 Filelnputstream(文件字节输入流)-CSDN博客https://blog.csdn.net/m0_65277261/article/details/136631816?spm=1001.2014.3001.5501【java基础】异常处理机制-CSDN博客https://blog.csdn.net/m0_65277261/article/details/136581375?spm=1001.2014.3001.5501【数据结构】二叉查找树和平衡二叉树,以及二者的区别_二叉查找树和其他二叉树的区别-CSDN博客https://blog.csdn.net/m0_65277261/article/details/136137098?spm=1001.2014.3001.5501