字符流
由于字节流操作中文不是特别的方便,所以Java就提供了字符流
字符流=字节流+编码表
计算机的信息都是用二进制数表示的
按照某种规则,将字符存储到计算机中,称为编码
将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码
字符编码:就是一套自然语言的字符与二进制数之间的对应规则(A,65)
字符集:是一个系统支持的所有的字符的集合
现在国际上通用的字符编码格式是UTF-8
总结:采用何种规则编码,就要采用对应规则解码,否则就会出现乱码
字符串中的编码解码问题
编码
- byte[] getBytes():使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
- byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
解码
- String(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的String
- String(byte[] bytes,String charsetName):通过指定的字符集解码指定的字节数组来构造新的String
String s="中国";
//对字符串进行编码得到字节数组
//不同的编码规则所得到的字节数组不一样
//utf-8编码,一个字由三个字节组成
//gbk编码,一个字由两个字节组成
byte[] bys = s.getBytes();//[-28, -72, -83, -27, -101, -67]
byte[] bys = s.getBytes("utf-8");//[-28, -72, -83, -27, -101, -67]
byte[] bys = s.getBytes("gbk");//[-42, -48, -71, -6]
//解码
//默认字符集
String ss=new String(bys);//中国
//指定字符集
String ss=new String(bys,"utf-8");//中国
String ss=new String(bys,"gbk");//涓浗,出现乱码,解码与编码的字符集格式不一样就会出现乱码
字符流中的编码解码问题
字符流抽象基类
- Reader:字符输入流的抽象类
- Writer:字符输出流的抽象类
字符流中和编码解码问题相关的两个类
- InputStreamReader
- OutputStreamWriter
InputStreamReader:是从字节流到字符流的桥梁
-
它读取字节,并使用指定的编码将其解码为字符
-
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
OutputStreamWriter:是从字符流到字节流的桥梁
-
是从字符流到字节流的桥梁,使用指定的charset将写入的字符编码为字节
-
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("文件路径\\要写入的文件.txt"),"编码字符集");
osw.write("好好学习,天天向上");
osw.close();
InputStreamReader isr = new InputStreamReader(new FileInputStream("文件路径\\要读的已经编码好的文件.txt"),"解码字符集");
//一次读一个字符
int ch;
while((ch=isr.read())!=-1){
System.out.print((char) ch);
}
isr.close();
字符输入流和字符输出流的便携流的子类
InputStreamReader的子类FileReader
- 常用构造方法-----FileReader(String fileName)创建一个新的 FileReader ,给定要读取的文件的名称。
- 拥有父类读数据的所有方法,以及默认字符编码
- 如果需要定义编码格式,则不能使用此子类
OutputStreamWriter的子类FileWriter
- 常用构造方法-----public FileWriter(String fileName)构造一个给定文件名的FileWriter对象。
- 拥有父类写数据的所有方法,以及默认字符编码
- 如果需要定义编码格式,则不能使用此子类
字符流写数据的5种方式
方法名 | 作用 |
---|---|
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) | 写一个字符串的一部分 |
字符流读数据的2种方式
方法名 | 作用 |
---|---|
int read() | 一次读一个字符数据 |
int read(char[] cbuf) | 一次读一个字符数组数据 |
字符缓冲流
字符缓冲流
- BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小;默认值足够大,可用于大多数用途
- BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小,默认值足够大,可用于大多数用途
构造方法
- BufferedWriter(Writer out)
- BufferedReader(Reader in)
字符缓冲流特有功能
BufferedWriter
- void newLine():写一行行分隔符,行分隔符字符串由系统属性定义
BufferedReader
- public String readLine():读一行文字,结果包含行的内容的字符串,不包括任何终止字符,如果流的结尾已经到达,则为null
//使用字符缓冲流的特有功能读写数据(此文件用文本查看器打开一定是都能看懂的字符)
//创建字符缓冲输入流
BufferedReader br=new BufferedReader(FileReader("要读取的文件路径"));
//创建字符缓冲输出流
BufferedWriter bw=new BufferedWriter(FileWriter("要写入的文件路径"));
//定义一个字符串变量接收每一次读取的一行数据
String line;
while((line=br.readline())!=null){
bw.write(line);
bw.newline();
bw.flush();
}
注意事项
- 字符缓冲输出流的方法-------public void flush()刷新流。
字符缓冲输出流,每一次写数据都要使用flush()方法刷新一下,如果写数据的次数比较多的时候,没有刷新流的情况下,会导致数据没有写进去