Day19-2
1 字符流
1.1为什么使用字符流:
- 如果想要一次写一个字符串,使用字节流可以完成,但是需要将字符串进行转换为 字节数组。
- 如果想要从一个文件中读取信息,进行展示
(1)这个文件中如果是全英文,可以一次读取一个字节,进行转换
(2)如果全是中文,可以使用字节流一次读取多个字节,将读取的字节转为一个字符串,进行展示
(3)如果文件中是中英文混杂,这时不知道读取几个字节进行转换,容易发生乱码。
1.2 概述
- 字符流:可以以字符为单位操作数据的输入和输出的对象所属的类型
- 分类:
字符输入流 Reader
字符输出流 Writer
2 Reader
- 字符输入流,也是一个抽象父类,不能直接创建对象
- 方法:
函数 | Value |
---|---|
read() | 读取一个字符信息,将读到的信息进行返回 |
read(char[] c) | 读取c.length个字符到数组中,返回的是读取的字符个数 |
read(char[] c,in t offset,int len) | 读取一部分字符到数组中 |
close() | 关闭流资源 |
- 使用子类创建对象:
FileReader
FileReader(File file)
FileReader(String fileName)
代码
package demos3_reader_writer;
import java.io.FileReader;
import java.io.IOException;
public class Demo02 {
public static void main(String[] args) throws IOException {
//创建一个字符输入流
FileReader fr = new FileReader("day19/src/a.txt");
//使用循环,一次读取一个字符信息
int i;
while((i = fr.read()) != -1){
System.out.println((char)i);
}
char[] chs = new char[10];
//一次读取多个,读取到数组中,将读取的个数返回
// int len = fr.read(chs);
//一次读取指定个数,读取到数组中,将读取的个数返回
int len = fr.read(chs, 2, 3);
System.out.println(chs);
System.out.println(len);
//关闭流资源
fr.close();
}
}
3 Writer
- 字符输出流,是一个抽象父类,不能直接创建对象
- 方法:
函数 | Value |
---|---|
write(int c) | 写出一个字符 |
write(String str) | 写出一个字符串 |
write(char[] cbuf) | 写出一个数组中的字符 |
write(char[] cbuf, int off, int len) | 写出数组的一部分到目标文件 |
write(String str, int off, int len) | 写出字符串的一部分 |
close() | 关闭流资源 |
- FileWriter:文件字符输出流
FileWriter(File file)
FileWriter(String fileName)
- 注意:
字符输出流,类型中维护了一个数组(自带缓冲区)
写出信息之后,需要关流或者刷新
代码
package demos3_reader_writer;
import java.io.FileWriter;
import java.io.IOException;
public class Demo03 {
public static void main(String[] args) throws IOException {
//创建一个字符输出流
FileWriter fw = new FileWriter("day19/src/b.txt");
//写出信息
//写一个字符
fw.write('你');
//写一个字符串
fw.write("你好吗?");
//写出一个字符数组
char[] chs = {'a','b','c'};
fw.write(chs);
//写出字符数组的一部分
char[] chs2 = {'h','e','l','l','o'};
fw.write(chs2,0,4);
//写出字符串的一部分
fw.write("java",2,2);
//关流或者刷新
fw.close();
}
}
4 使用字符流拷贝文件
-
概述:将文件中的内容赋值到另一个文件中
-
思路:
先使用字符输入流读取信息,再使用字符输出流写出信息 -
图示:
-
注意:
如果仅仅为了拷贝一个文件,没有必要使用字符流,因为字符流底层也是调用了字节流,而且还多个两步编码解码操作,浪费时间。直接使用字节流即可。
如果想要获取文本中的内容,可以使用字符流读取,因为可以读取任何字符
如果想要写出一些内容到文本中,可以使用字符流写出,因为可以写出字符串 -
为了提高拷贝的效率,可以使用小数组来拷贝文件。
代码
package demos3_reader_writer;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Demo04 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("day19/src/a.txt");
FileWriter fw = new FileWriter("day19/src/acopy.txt");
int i;
while((i = fr.read()) != -1){
fw.write(i);
}
fr.close();
fw.close();
}
}
4.1 可不可以使用字符流拷贝非纯文本文件?
- 纯文本文件:全部都是以字符信息表示的数据
- 非纯文本文件:视频、图片、音频等等不是通过字符表示数据的文件
- 答案:不可以拷贝
如果文件是一个纯文本,文本中保存的字节,在编码表中肯定有字符与之对应。
如果文件是一个非纯文本,非纯文本中保存的字节,在编码表中可能没有对应的字符。
如果读取一个非纯文本文件中的字节,该字节没有对应的字符,默认使用一个?字符来 代替,再写出的时候,就将?字符对应的整数写出,这一步发生了信息的篡改,所以就 导致本来的文件不能正常使用。
5 高效缓冲字符流
- 类型:BufferedReader和BufferedWriter
- 概述:都是包装类型,需要对基础的字符流对象进行包装。包装之后,一次也可以读取 多个字 符,可以写出多个字符。
- 构造:BufferedReader(Reader in)
方法:readLine() :一次可以从输入流中读取一行信息
返回值就是读取的这一行数据,如果到达文件的末尾,返回null - 构造:BufferedWriter(Writer out)
方法:newLine() :表示在文件中进行换行
代码
package demos3_reader_writer;
import java.io.*;
public class Demo06 {
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("day19/src/a2.txt"));
bw.write("你好你好");
bw.newLine();
bw.write("你今天吃饭了吗");
bw.newLine();
bw.write("你吃了吗");
bw.close();
}
private static void test2() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("day19/src/a.txt"));
String str;
while((str = br.readLine()) != null){
System.out.println(str);
}
br.close();
}
private static void test() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("day19/src/a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("day19/src/a2.txt"));
int i;
while((i = br.read()) != -1){
bw.write(i);
}
br.close();
bw.close();
}
}
6 练习
- 将一个文件中的信息,反转到另外一个文件中
反转:按行来反转
代码
package demos3_reader_writer;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
public class Test01 {
// 1、将一个文件中的信息,反转到另外一个文件中
// 反转:按行来反转
public static void main(String[] args) throws IOException {
//将读取的每一行信息,保存在一个容器中
//将该容器中的数据,进行反转
ArrayList<String> list = new ArrayList<>();
BufferedReader br = new BufferedReader(new FileReader("day19/src/Demo01.java"));
BufferedWriter bw = new BufferedWriter(new FileWriter("day19/src/D.java"));
String str;
//将读取的每一行信息,保存在集合中(有序)
while((str = br.readLine()) != null){
list.add(str);
}
br.close();
//将集合中的数据,反转 表示读取的每一行信息反转
Collections.reverse(list);
//遍历反转后的集合,获取每一个数据 就是每一行信息
for(String s:list){
bw.write(s);
bw.newLine();
}
bw.close();
}
}