Reader
java.io.Reader
抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。
方法名
说明
public void close()
关闭此流并释放与此流相关联的任何系统资源。
public int read()
从输入流读取一个字符。
public int read(char[] cbuf)
从输入流中读取一些字符,并将它们存储到字符数组 cbuf中
FileReader类
java.io.FileReader
类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
==注意事项==
- 字符编码:字节与字符的对应规则。Windows系统的中文编码默认是GBK编码表。idea中UTF-8
- 字节缓冲区:一个字节数组,用来临时存储字节数据。
FileReader类构造方法
方法名
说明
FileReader(File file)
创建一个新的 FileReader ,给定要读取的File对象。
FileReader(String fileName)
创建一个新的 FileReader ,给定要读取的文件的名称。
当你创建一个流对象时,必须传入一个文件路径。类似于FileInputStream 。
代码演示
public class FileReaderConstructor throws IOException{
public static void main(String[] args) {
// 使用File对象创建流对象
File file = new File("a.txt");
FileReader fr = new FileReader(file);
// 使用文件名称创建流对象
FileReader fr = new FileReader("b.txt");
}
}
读取字符数据
一次读取一个字符
read
方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1
public class FRRead {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileReader fr = new FileReader("read.txt");
int read = fr.read();
System.out.println((char) read);
int read2 = fr.read();
System.out.println((char) read2);
int read3 = fr.read();
System.out.println((char) read3); //读不到返回-1
// 定义变量,保存数据
int b;
// 循环读取
while ((b = fr.read())!=-1) {
System.out.println((char)b);
}
// 关闭资源
fr.close();
}
}
一次读取一个字符数组
read(char[] cbuf)
,每次读取b的长度个字符到数组中,返回读取到的有效字符个数,读取到末尾时,返回-1
public class FRRead {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileReader fr = new FileReader("read.txt");
// 定义变量,保存有效字符个数
int len ;
// 定义字符数组,作为装字符数据的容器
char[] cbuf = new char[1024];
// 循环读取
while ((len = fr.read(cbuf))!=-1) {
System.out.println(new String(cbuf,0,len));
}
// 关闭资源
fr.close();
}
}
Writer
java.io.Writer
抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。
方法名
说明
void write(int c)
写入单个字符
void write(char[] cbuf)
写入字符数组。
abstract void write(char[] cbuf, int off, int len)
写入字符数组的某一部分,off数组的开始索引,len写的字符个数
void write(String str)
写入字符串
void write(String str, int off, int len)
写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
void flush()
刷新该流的缓冲。
void close()
关闭此流,但要先刷新它。
FileWriter类
java.io.FileWriter
类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
4.4.1 FileWriter类构造方法
方法名
说明
FileWriter(File file)
创建一个新的 FileWriter,给定要读取的File对象。
FileWriter(String fileName)
创建一个新的 FileWriter,给定要读取的文件的名称。
当你创建一个流对象时,必须传入一个文件路径,类似于FileOutputStream。
代码演示
public class FileWriterConstructor {
public static void main(String[] args) throws IOException {
// 使用File对象创建流对象
File file = new File("a.txt");
FileWriter fw = new FileWriter(file);
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("b.txt");
}
}
写数据
一次写一个字符
write(int b)
方法,每次可以写出一个字符数据
public class FWWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt");
// 写出数据
fw.write(97); // 写出第1个字符
fw.write('b'); // 写出第2个字符
fw.write('C'); // 写出第3个字符
fw.write(30000); // 写出第4个字符,中文编码表中30000对应一个汉字。
/*
【注意】关闭资源时,与FileOutputStream不同。
如果不关闭,数据只是保存到缓冲区,并未保存到文件。
*/
// fw.close();
}
}
flush与close之间的区别
因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要
flush
方法了。
flush
:刷新缓冲区,流对象可以继续使用。close
: 先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
注意:字符流一定要flush
字节流是直接与数据产生交互,而字符流在与数据交互之前要经过一个缓冲区 。
为什么字符流要flush呢?
因为字符流数据没有直接进文件而是进缓存区
关闭流之前会自动刷新
面试题:close()和flush()的区别?
A:close()关闭流对象,但是先刷新一次缓冲区。关闭之后,流对象不可以继续再使用了。
B:flush()仅仅刷新缓冲区,刷新之后,流对象还可以继续使用。
代码演示
public class FWWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt");
// 写出数据,通过flush
fw.write('刷'); // 写出第1个字符
fw.flush();
fw.write('新'); // 继续写出第2个字符,写出成功
fw.flush();
// 写出数据,通过close
fw.write('关'); // 写出第1个字符
fw.close();
fw.write('闭'); // 继续写出第2个字符,【报错】java.io.IOException: Stream closed
fw.close();
}
}
==注意:== 即便是flush方法写出了数据,操作的最后还是要调用close方法,释放系统资源。
一次写一个字符数组
write(char[] cbuf)
和write(char[] cbuf, int off, int len)
,每次可以写出字符数组中的数据,用法类似FileOutputStream
public class FWWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt");
// 字符串转换为字节数组
//char[] ch = {'h','e','l'};
char[] chars = "Hello".toCharArray();
// 写出字符数组
fw.write(chars); // Hello
fw.write(b,2,2);
// 关闭资源
fos.close();
}
}
一次写一个字符串
write(String str)
和write(String str, int off, int len)
,每次可以写出字符串中的数据,更为方便
public class FWWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt");
// 字符串
fw.write("Hello"); //Hello
fw.write(msg,2,2);
// 关闭资源
fos.close();
}
}
续写和换行
public class FWWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象,可以续写数据
FileWriter fw = new FileWriter("fw.txt",true);
// 写出字符串
fw.write("hello");
// 写出换行
fw.write("\r\n");
// 写出字符串
fw.write("world");
// 关闭资源
fw.close();
}
}
字符复制
//读
FileReader fr = new FileReader("a.txt");
//写
FileWriter fd = new FileWriter("b.txt");
//复制
int len;
char[] chars = new char[1024*8];
while((len = fr.read(chars)) != -1){
fd.write(chars,0,len);
fd.flush();
}
fr.close();
fd.close();