Reader、Writer
IO 流体系图
Reader
Reader 是输 ⼊字符流的 ⽗类,它是 ⼀个抽象类, 部分库不推荐使 ⽤ Reader/Writer。
常见方法
//⼀个字符⼀个字符的读,只能⽤来操作⽂本(不能写图⽚ ⾳频 视频)
int read()
//从输⼊字符流中读取⼀定数量的字符,并将其存储在缓冲区数组cbuf中, 返回实际读取的字符 数,如果已经到达流末尾⽽没有可⽤的字节,则返回-1
int read(char cbuf[])
//关闭输⼊流并释放与该流关联的系统资源
void close() throws IOException
FileReader
用来读取字符 ⽂件的实现类。
/**
* 读取中⽂显示出来, java运⾏时采⽤utf16编码,多数汉字占2个字节,⼀个char就够,少数占4个字节,需要两个char来表示
*/
@Test
public void readerCharArrayTesting() throws IOException {
String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
File file = new File(filePath);
FileReader input = new FileReader(file);
int size;
char[] ch = new char[1024];
while ((size = input.read(ch)) != -1){
System.out.print(new String(ch,0,size));
}
input.close();
}
Writer
Writer 是输出字符流的 ⽗类,它是 ⼀个抽象类。
//直接将int型数据作为参数的话,是不会写⼊数字的,⽽是现将数字按照ascll码表转换为 相应的字符,然后写⼊
public void write(int c) throws IOException
//要想实现数字和中⽂的写⼊,必须要⽤String为参数的Write
public void write(String str) throws IOException
//将cbuf字符数组的⼀部分写⼊到流中,但能不能写len个字符取决于cbuf中是否有那么多
public abstract void write(char cbuf[], int off, int len) throws IOException;
//write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会⾃动将缓冲区的内容写⼊ ⽂件,但是⼀般还有⼀部分有可能会留在内存这个缓冲区中, 所以需要调⽤flush空缓冲区数据。 对⽐BufferWriter需要实时查表,效率低,其实缓冲区IO的各个都有,只不过很⼩被忽 略,OutputStream都有flush⽅法,看⼦类是否有重写
void flush() throws IOException
//关闭输⼊流并释放与该流关联的系统资源
void close() throws IOException
FileWriter
⽤来写出字符 ⽂件的实现类。
//如果⽂件不存在,这会⾃动创建。如果⽂件存在,则会覆盖
public FileWriter(String fileName) throws IOException
//如果⽂件不存在,这会⾃动创建。如果⽂件存在,则会覆盖
public FileWriter(File file) throws IOException
//加⼊true参数,会实现对⽂件的续写,使⽤false则会实现对⽂件的覆盖
public FileWriter(String fileName, boolean append) throws IOException
//加⼊true参数,会实现对⽂件的续写,使⽤false则会实现对⽂件的覆盖
public FileWriter(File file, boolean append) throws IOException
示例
/**
* 传入int类型参数会查表 ASCII码 查表会消耗性能
* 传入string类型参数 不会查表,直接写入,没有多余的性能开销
* @throws IOException
*/
@Test
public void writerTesting() throws IOException {
String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\2.txt";
FileWriter writer = new FileWriter(filePath);
//FileWriter writer = new FileWriter(filePath,true); //追加
//FileWriter writer = new FileWriter(filePath,false); //覆盖
writer.write(23567); //小
writer.write(28404); //滴
writer.write(35838); //课
writer.write(22530); //堂
writer.write("23567"); //23567
writer.flush();
writer.close();
}
BufferedReader
为了提 ⾼了单个字符读写的效率,进 ⾏字符批量的读写; 为了提 ⾼字符流读写的效率,引 ⼊了缓冲机制。
当 BufferedReader 在读取 ⽂本 ⽂件时,会先尽量从 ⽂件中读 ⼊字符数据并放满缓冲 区,⽽之后若使 ⽤ read()⽅法,会先从缓冲区中进 ⾏读取。如果缓冲区数据不 ⾜,才会再从 ⽂ 件中读取。
构造函数
BufferedReader(Reader in)
//创建⼀个使⽤指定⼤⼩输⼊缓冲区的缓冲字符输⼊流。
BufferedReader(Reader in, int sz)
常用 API
//判断此流是否已准备好被读取,依赖其他流,所以⼀般需要做判断
boolean ready()
//读取单个字符
int read()
//读取⼀部分字符到数组⾥⾯,从数组下标off处放置length⻓度的字符
int read(char[] cbuf, int off, int len)
//读取⼀整⾏⽂本⾏,返回⼀整⾏字符串,如果读到⾏尾了就返回null,注意返回的⼀⾏字符中不 包含换⾏符
String readLine()
//读取⼀整⾏⽂本⾏,返回⼀整⾏字符串,如果读到⾏尾了就返回null,注意返回的⼀⾏字符中不 包含换⾏符
String readLine()
示例
/**
* read()
* @throws IOException
*/
@Test
public void bufferedWriterTesting() throws IOException {
String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
if (!bufferedReader.ready()) {
System.out.println("文件流暂时无法读取");
return;
}
int size;
char[] cbuf = new char[1024];
while ((size = bufferedReader.read(cbuf, 0, cbuf.length)) != -1) {
System.out.println(new String(cbuf,0,size));
}
}
/**
* readLine()
* @throws IOException
*/
@Test
public void bufferedWriterReadlineTesting() throws IOException {
String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
if (!bufferedReader.ready()) {
System.out.println("文件流暂时无法读取");
return;
}
String str = "";
while ((str = bufferedReader.readLine()) != null) {
System.out.println(str);
}
bufferedReader.close();
}
BufferedWriter
写 ⼊的数据并不会先输出到 ⽬的地,⽽是先存储 ⾄缓冲区中。如果缓冲区中的数据满 了,才会 ⼀次对 ⽬的地进 ⾏写出。
构造函数
BufferedWriter(Writer out)
BufferedWriter(Writer out, int sz)
常用 API
//写⼊⼀个字符
void write(int c)
//写⼊字符数组的⼀部分,通过off和len控制。
void write(char[] cbuf, int off, int len)
//写⼊字符串的⼀部分,通过off和len控制。
void write(String s, int off, int len)
//写如⼀个换⾏符合
void newLine()
//关闭输⼊流并释放与该流关联的系统资源
void close()
//write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会⾃动将缓冲区的内容 写⼊⽂件,但是⼀般还有⼀部分有可能会留在内存这个缓冲区中, 所以需要调⽤flush空缓 冲区数据。
void flush()
示例
@Test
public void BufferedWriterTest() throws IOException {
String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\2.txt";
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
//写入一个字符
char ch = '你';
bufferedWriter.write(ch);
//写入一个字符数组
String strArray = "好!北京欢迎你!";
bufferedWriter.write(strArray.toCharArray(),0,strArray.length());
//写入一个换行符
bufferedWriter.newLine();
//写入一个字符串
String newStr = "哈哈哈!";
bufferedWriter.write(newStr);
//关闭资源
bufferedWriter.close();
//你好!北京欢迎你!
//哈哈哈!
}
InputStreamReader
计算机存储的单位是字节,从持久设备读取到程序中是解码,从程序写到持久设备中是编码 不管是编码还是解码,不同字符集编解码成 字符 需要不同的个数,因此字节流读取容易出错,⽐ 如乱码。
需要 ⼀个流,把字节流读取的字节进 ⾏缓冲后,在通过字符集解码成字符返回。
InputStreamReader(继承 Reader)
将字节流转换为字符流, 字节流通向字符流的桥梁,如果不指定字符集编码,则解码过程 将使 ⽤平台默认的字符编码,如:UTF-8
⽂本 ⽂件存储是 A 编码,然后如果以 B 编码进 ⾏读取则会乱码
构造函数
//使⽤系统默认编码集
public InputStreamReader(InputStream in)
//指定指定编码集创建对象
public InputStreamReader(InputStream in, String charsetName)
常用 API
//读取单个字符
int read()
//读取⼀部分字符到数组⾥⾯,从数组下标off处放置length⻓度的字符
int read(char[] cbuf, int off, int len)
//将读取到的字符存到数组中,返回读取的字符数
int read(char []cbuf)
//关闭流释放资源
void close()
示例
@Test
public void inputStreamReadTesting() throws IOException {
String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
//读取字节流
InputStream inputStream = new FileInputStream(filePath);
//字节流向字符流转换: 转换之后变为InputStreamReader 属于 字符流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");//默认解码采用UTF-8
//字符流缓冲区对 InputStreamReader 进行包装,提高性能
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
inputStream.close();
bufferedReader.close();
}
OutputStreamWriter
将字符流转换为字节流(看源码解释), 字符流通向字节流的桥梁,如果不指定字符集编码,则编码过程将使 ⽤平台默认的字符编码,如:GBK
构造函数
//使⽤系统默认编码集
public OutputStreamWriter(OutputStream out)
//指定指定编码集创建对象
public OutputStreamWriter(OutputStream out, String charsetName)
常用 API
//写⼊⼀个字符
void write(int c)
//写⼊字符数组的⼀部分,通过off和len控制。
void write(char[] cbuf, int off, int len)
//写⼊字符数组的⼀部分,通过off和len控制。
void write(String s, int off, int len)
//写如⼀个换⾏符合
void newLine()
//关闭输⼊流并释放与该流关联的系统资源
void close()
//write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会⾃动将缓冲区的内容 写⼊⽂件,但是⼀般还有⼀部分有可能会留在内存这个缓冲区中, 所以需要调⽤flush空缓 冲区数据。
void flush()
示例
@Test
public void outputStreamReadTesting() throws IOException {
String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\2.txt";
//写入字节流
OutputStream outputStream = new FileOutputStream(filePath);
//将写入字符流转成写入字节流
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream,"UTF-8");//默认的编码是UTF-8
//采用Buffered包装写入字符流
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
String str = "北京欢迎你! Welcome to Bei Jing! ";
bufferedWriter.write(str);
bufferedWriter.newLine();
bufferedWriter.write("哈哈哈!~");
bufferedWriter.flush();
bufferedWriter.close();
//北京欢迎你! Welcome to Bei Jing!
//哈哈哈!~
}