Java高级_Day12(字符流,编码表)
字符流
字符流的出现主要是为解决中文等特殊字符的处理
字符流的本质 = 字节流 + 编码
中文的识别:在编码中,如果 存储的是中文,那么第一个字节一定是负数
编码表
按照某种规则,将字符存储到计算机中,称为编码。
反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码 。
在编码和解码的过程中,所使用的编码表必须一致,否则就有可能会出现乱码
字符编码:就是一套自然语言的字符与二进制数之间的对应规则(A,65)
字符集:
- 是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
- 计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBXXX字符集、Unicode字符集等
常见的字符集:
- ASCII(American Standard Code for Information Interchange,美国信息交换标准代码):是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)
- ISO-8859-1 欧洲字符集 主要表示所有的欧洲字符
- GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等
- UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用 中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。它使用一至四个字节为每个字符编码
编码规则:
- 128个US-ASCII字符,只需一个字节编码
- 拉丁文等字符,需要二个字节编码
- 大部分常用字(含中文),使用三个字节编码
- 其他极少使用的Unicode辅助字符,使用四字节编码
采用何种规则编码,就要采用对应规则解码,否则就会出现乱码
字符串中的编码解码问题
编码:
返回值类型 | 方法 |
---|---|
byte[] | getBytes() 使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中。 |
byte[] | getBytes(String charsetName) 使用命名的字符集将此 String编码为字节序列,将结果存储到新的字节数组中。 |
解码:
String(byte[] bytes)
通过使用平台的默认字符集解码指定的字节数组来构造新的 String 。String(byte[] bytes, int offset, int length)
通过使用平台的默认字符集解码指定的字节子阵列来构造新的 String 。String(byte[] bytes, int offset, int length, String charsetName)
构造一个新的 String通过使用指定的字符集解码指定的字节子阵列。String(byte[] bytes, String charsetName)
构造一个新的String由指定用指定的字节的数组解码charset 。
public static void main(String[] args) throws UnsupportedEncodingException {
// UTF-8 一个汉字是三个字节 GBK编码中 一个汉字是两个字节
String str = "中北大学";
// byte[] strByte =str.getBytes();
//编码
byte[] strByte = str.getBytes("utf-8");
for(byte b :strByte){
System.out.println(b);
}
//解码
String strSrc = new String(strByte,"UTF-8");
System.out.println(strSrc);
}
字符流的抽象基类:
public abstract class Reader
返回值类型 | 方法 |
---|---|
int | read() 读一个字符 |
int | read(char[] cbuf) 将字符读入数组 |
abstract int | read(char[] cbuf,int off,int len) 将字符读入数组的一部分 |
public abstract class Writer
返回值类型 | 方法 |
---|---|
void | write(char[] cbuf) 写入一个字符数组。 |
abstract void | write(char[] cbuf, int off, int len) 写入字符数组的一部分。 |
void | write(int c) 写一个字符 |
void | write(String str) 写一个字符串 |
void | write(String str, int off, int len) 写一个字符串的一部分。 |
字符流中的实现类:
OutputStreamWriter:
- OutputStreamWriter是字符的桥梁流以字节流:向其写入的字符编码成使用指定的字节charset 。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。
OutputStreamWriter(OutputStream out)
创建一个使用默认字符编码的OutputStreamWriter。OutputStreamWriter(OutputStream out, Charset cs)
创建一个使用给定字符集的OutputStreamWriter。OutputStreamWriter(OutputStream out, CharsetEncoder enc)
创建一个使用给定字符集编码器的OutputStreamWriter。OutputStreamWriter(OutputStream out, String charsetName)
创建一个使用命名字符集的OutputStreamWriter。
返回值类型 | 方法 |
---|---|
String | getEncoding() 返回此流使用的字符编码的名称。 |
void | write(char[] cbuf, int off, int len) 写入字符数组的一部分。 |
void | write(int c) 写一个字符 |
void | write(String str, int off, int len) 写一个字符串的一部分。 |
字符流默认带有缓冲区 如果写出的内容没有填满缓冲区,则需要flush或者close
InputStreamReader:
- InputStreamReader是从字节流到字符流的桥:它读取字节,并使用指定的charset将其解码为字符 。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。
InputStreamReader(InputStream in)
创建一个使用默认字符集的InputStreamReader。InputStreamReader(InputStream in, Charset cs)
创建一个使用给定字符集的InputStreamReader。InputStreamReader(InputStream in, CharsetDecoder dec)
创建一个使用给定字符集解码器的InputStreamReader。InputStreamReader(InputStream in, String charsetName)
创建一个使用命名字符集的InputStreamReader。
返回值类型 | 方法 |
---|---|
String | getEncoding() 返回此流使用的字符编码的名称。 |
int | read() 读一个字符 |
int | read(char[] cbuf, int offset, int length) 将字符读入数组的一部分。 |
public static void main(String[] args) throws IOException {
//创建一个字符流
FileOutputStream fis = new FileOutputStream("day_12_ReaderAndWriter\\dir\\osw.txt");
OutputStreamWriter osw = new OutputStreamWriter(fis);
osw.write("中北大学");
osw.write("中国加油");
osw.flush();
osw.close();
// 使用字符流读取文件
InputStream in = new FileInputStream("day_12_ReaderAndWriter\\dir\\osw.txt");
InputStreamReader isr = new InputStreamReader(in);
// int ch ;
// while((ch = isr.read()) != -1){
// System.out.println((char)ch);
// }
char[] chars = new char[1024];
int len ;
while((len = isr.read(chars)) != -1){
System.out.println(new String(chars));
}
}
使用字符流实现文件的复制,采用默认字符集:
public static void main(String[] args) throws IOException {
// 实现对dir目录下的sw.java文件的一个的拷贝
//创建一个字符输入流读取文件
InputStreamReader isr = new InputStreamReader(new FileInputStream("day_12_ReaderAndWriter\\dir\\sw.java"));
// 创建输出流
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day_12_ReaderAndWriter\\dir\\ow.java"));
//进行读写操作
char[] chars = new char[1024];
int len;
while((len = isr.read(chars)) != -1){
osw.write(chars,0,len);
}
osw.close();
isr.close();
}
采用指定的字符集完成文件的拷贝:
public static void main(String[] args) throws IOException {
// 实现对dir目录下的sw.java文件的一个的拷贝
//创建一个字符输入流读取文件 如果指定字符集 则输入流和输出流必须采用相同的字符集
InputStreamReader isr = new InputStreamReader(new FileInputStream("day_12_ReaderAndWriter\\dir\\sw.java"),"UTF-8");
// 创建输出流
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day_12_ReaderAndWriter\\dir\\ow.java"),"GBK");
//进行读写操作
char[] chars = new char[1024];
int len;
while((len = isr.read(chars)) != -1){
osw.write(chars,0,len);
}
osw.close();
isr.close();
}
InputStreamReader和 OutputStreamWriter 实现了将字节流转换为字符流的功能 因此 也称为转换流
转换流的简写形式:
对于上述两个转换流的简写形式:他们的直接子类 FileReader FilerWriter
使用转换流的简写形式完成文件的拷贝
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("day_12_ReaderAndWriter\\dir\\sw.java");
FileWriter fw= new FileWriter("day_12_ReaderAndWriter\\dir\\fw.java");
char[] cbuff = new char[1024];
int len;
while((len = fr.read(cbuff)) != -1){
fw.write(cbuff,0 ,len);
}
fw.close();
fr.close();
}
字符流和字节流的使用场景:
- 字符流主要用来完成纯文本文件的读写
- 字节流可以完成纯文本文件,图片 ,视频,音频等各种文件的读写。在使用的时候,如果不知道该用什么流,那么首选字节流。
word文档不是纯文本文件。