「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战」
一、为什么出现字符流
- 由于字节流操作中文不是特别的方便,所以Java就提供字符流
- 字符流=字节流+编码表
- 用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
- 汉字在存储的时候, 无论选择哪种编码存储,第一个字节都是负数
二、字符流中编码解码问题
- 字符流抽象基类
- Reader:字符输入流的抽象类
- Writer:字符输出流的抽象类
- 字符流中和编码解码问题相关的两个类:
InputStreamReader:从字节流到字符流的桥梁 它读取字节,并使用指定的编码将其解码为字符 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集OutputStreamWriter:是从字符流到字节流的桥梁 是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
package test;
import java.io.*;
public class Demo {
public static void main(String[] args) throws IOException {
// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\fos.txt"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\fos.txt"),"GBK");
osw.write("中国");
osw.close();
//1, InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\test\\fos.txt"));
InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\test\\fos.txt"),"GBK");
int ch;
while((ch= isr.read()) !=-1) {
System.out.print((char)ch); //1:�й�;2:中国,因为第二次和编码格式GBK一样
}
isr.close();
}
}
三、字符输出流
| 方法名 | 说明 |
|---|---|
| void write(int c) | 写一个字符 |
| void write(char[ ] cbuf) | 写一个字符数组 |
| void write(char[ ] cbuf,int off,int len) | 写一个字符数组的一部分 |
| void write(String str) | 写一个字符串 |
| void write(String str,int off,int len) | 写一个字符串的一部分 |
| 方法名 | 说明 |
|---|---|
| flush() | 刷新流还可以写数据 |
| close() | 关闭流,释放资源,但在关闭之前先刷新。关闭后不能写数据 |
- 范例
package test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\fos.txt"));
//1,void write(int c) 写一个字符
/*osw.write(97);
osw.write(98);
//ab
//void flush():刷新流
osw.flush();*/
//2,void write(char[ ] cbuf) 写一个字符数组
/*char[] chs = {'a','b','c'};
// osw.write(chs);
//abc
//3,void write(char[ ] cbuf,int off,int len) 写一个字符数组的一部分
osw.write(chs,1, 2); //bc,1索引开始,写两个*/
//4,void write(String str) 写一个字符串
// osw.write("abcef"); //abcef
//5,void write(String str,int off,int len) 写一个字符串的一部分
osw.write("abcdef",0, "abcdef".length()); //abcdef
osw.close();
}
}
四、字符输入流
| 方法名 | 说明 |
|---|---|
| int read() | 一次读一个字符数据 |
| int read(char([ ] cbuf) | 一次读一个字符数组数据 |
五、字符缓冲流
BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。默认值足够大,可用于大多数用途BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途- 构造方法
- BufferedReader(Reader in)
- BufferedWriter(Writer out)
六、字符缓冲流特有功能
BufferedReader
public String readLine():读一行文字。结果包含行的内容的字符串,不包括任何行终止字符,如果流的结尾已经到达,则为null
BufferedWriter
void newLine():写一行行分隔符, 行分隔符字符串由系统属性定义
package test;
import java.io.*;
public class BufferedStreamDemo {
public static void main(String[] args) throws IOException {
//创建字符缓冲流输出流
/*BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\fos.txt"));
for(int i=0;i<5;i++) {
bw.write("hello"+i);
// bw.write("\r\n");
//2,void newLine():写一行行分隔符, 行分隔符字符串由系统属性定义
bw.newLine();
bw.flush();
}
bw.close();*/
//创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader("E:\\test\\fos.txt"));
//2,public String readLine():读一行文字
String line;
while((line=br.readLine()) != null) {
System.out.println(line);
/*
hello0
hello1
hello2
hello3
hello4*/
}
br.close();
}
}