什么是字符集
- 是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBXXX字符集、Unicode字符集等
常见的字符集
ASCII字符集:
- ASCII:是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)基本的ASCII字符集,使用7位表示一个字符,共128字符。ASCII的扩展字符集使用8位表示一个字符,共256字符,方便支持欧洲常用字符。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
GBXXX字符集:
GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等Unicode字符集:
- UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用 中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。它使用一至四个字节为每个字符编码编码规则:
128个US-ASCII字符,只需一个字节编码
拉丁文等字符,需要二个字节编码
大部分常用字(含中文),使用三个字节编码
其他极少使用的Unicode辅助字符,使用四字节编码
要点
问题
编码: 字符转成编号
解码: 把编号转成字符
编码表: 字符和编号之间的对应关系表
字符集: 字符的集合,字符集会对应一个编码表
常见编码表有哪些?
ASCII : 现代英语,美国
GB2312: 简体中文,7000字符
gbk:2万多字符,兼容GB2312
gb18030: 中文最全的码表,包含少数民族文字
iso-8859-1: 欧洲编码 ,拉丁字母
unicode码表: 万国码,全世界主要国家语言的文字字符.
utf-8 : 变长 英文一个,其他2个,中文3个,最多4个字节
utf-16: 固定长度,2个字节,4个字节
utf-32: 固定4个字节
2.关于字符流
- 字节流以字节为单位操作,读取中文可能有问题,因为中文字符与字节不是一个对应一个的关系(idea默认是utf-8编码,中文占3个字节,英文占一个字节,gbk 编码中文占2个字节,英文占一个)下面我们学习字符流,读取数据以字符为单位(中英文字符均可)字符流 = 字节流 + 编码表(utf-8)支持读取中文
相关方法
| 方法名 | 说明 |
|---|---|
| byte[] getBytes() | 使用平台的默认字符集将该 String编码为一系列字节 |
| byte[] getBytes(String charsetName) | 使用指定的字符集将该 String编码为一系列字节 |
| String(byte[] bytes) | 使用平台的默认字符集解码指定的字节数组来创建字符串 |
| String(byte[] bytes, String charsetName) | 通过指定的字符集解码指定的字节数组来创建字符串 |
代码示例
public class StringDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
//定义一个字符串
String s = "中国a";
byte[] bys1 = s.getBytes(); //[-28, -72, -83, -27, -101, -67, 97]
byte[] bys2 = s.getBytes("UTF-8"); //[-28, -72, -83, -27, -101, -67, 97]
byte[] bys3 = s.getBytes("GBK"); //[-42, -48, -71, -6, 97]
System.out.println(Arrays.toString(bys1));
System.out.println(Arrays.toString(bys2));
System.out.println(Arrays.toString(bys3));
//String ss = new String(bys);
//String ss = new String(bys,"UTF-8");
String ss = new String(bys3,"GBK");
System.out.println(ss);
}
}
4.字节流读取中文出现乱码的原因
字节与中文字符不是一一对应的关系!
由于字节流操作 中文 不是特别的方便,所以Java就提供字符流
字符流 = 字节流 + 编码表 !
介绍
Writer:用于写入字符流的抽象父类
FileWriter:用于写入字符流的常用子类构造方法
| 方法名 | 说明 |
|---|---|
| FileWriter(File file) | 根据给定的 File 对象构造一个 FileWriter 对象 |
| FileWriter(File file, boolean append) | 根据给定的 File 对象构造一个 FileWriter 对象 |
| FileWriter(String fileName) | 根据给定的文件名构造一个 FileWriter 对象 |
| FileWriter(String fileName, boolean append) | 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象 |
成员方法
| 方法名 | 说明 |
|---|---|
| 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) | 写一个字符串的一部分 |
代码示例
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("myCharStream\a.txt");
//void write(int c):写一个字符
// fw.write(97);
// fw.write(98);
// fw.write(99);
//void writ(char[] cbuf):写入一个字符数组
char[] chs = {'a', 'b', 'c', 'd', 'e'};
// fw.write(chs);
//void write(char[] cbuf, int off, int len):写入字符数组的一部分
// fw.write(chs, 0, chs.length);
// fw.write(chs, 1, 3);
//void write(String str):写一个字符串
// fw.write("abcde");
//void write(String str, int off, int len):写一个字符串的一部分
// fw.write("abcde", 0, "abcde".length());
fw.write("abcde", 1, 3);
fw.write(System.lineSeparator());//换行符
//释放资源
fw.close();
}
}
7.字符流-写出数据的注意事项
8.字符流-flush和close方法
- flush(): 刷新流(发送缓冲区中的内容到目标文件) ,流还可以继续使用!close(): 1.会先刷新流,再关闭 , 关闭后,流不能再使用!
介绍
Reader: 用于读取字符流的抽象父类
FileReader: 用于读取字符流的常用子类构造方法
| 方法名 | 说明 |
|---|---|
| FileReader(File file) | 在给定从中读取数据的 File 的情况下创建一个新 FileReader |
| FileReader(String fileName) | 在给定从中读取数据的文件名的情况下创建一个新 FileReader |
成员方法
| 方法名 | 说明 |
|---|---|
| int read() | 一次读一个字符数据 |
| int read(char[] cbuf) | 一次读一个字符数组数据 |
代码示例
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("myCharStream\b.txt");
//int read():一次读一个字符数据
// int ch;
// while ((ch=fr.read())!=-1) {
// System.out.print((char)ch);
// }
//int read(char[] cbuf):一次读一个字符数组数据
char[] chs = new char[1024];
int len;
while ((len = fr.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}
//释放资源
fr.close();
}
}
10.字符缓冲输入流-读取数据
字符缓冲流介绍
BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途
构造方法
| 方法名 | 说明 |
|---|---|
| BufferedWriter(Writer out) | 创建字符缓冲输出流对象 |
| BufferedReader(Reader in) | 创建字符缓冲输入流对象 |
代码示例
public class BufferedStreamDemo01 {
public static void main(String[] args) throws IOException {
//BufferedWriter(Writer out)
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\bw.txt"));
bw.write("hellorn");
bw.write("worldrn");
bw.close();
//BufferedReader(Reader in)
BufferedReader br = new BufferedReader(new FileReader("myCharStream\bw.txt"));
//一次读取一个字符数据
// int ch;
// while ((ch=br.read())!=-1) {
// System.out.print((char)ch);
// }
//一次读取一个字符数组数据
char[] chs = new char[1024];
int len;
while ((len=br.read(chs))!=-1) {
System.out.print(new String(chs,0,len));
}
br.close();
}
}
11.缓冲流-特有方法
方法介绍
BufferedWriter:
| 方法名 | 说明 |
|---|---|
| void newline() | 写一行行分隔符,行分隔符字符串由系统属性定义 |
BufferedReader:
| 方法名 | 说明 |
|---|---|
| String readLine() | 读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null |
代码示例
public class BufferedStreamDemo02 {
public static void main(String[] args) throws IOException {
//创建字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\bw.txt"));
//写数据
for (int i = 0; i < 10; i++) {
bw.write("hello" + i);
//bw.write("rn");
bw.newline();
bw.flush();
}
//释放资源
bw.close();
//创建字符缓冲输入流
BufferedReader br = new BufferedReader(new FileReader("myCharStream\bw.txt"));
String line;
while ((line=br.readLine())!=null) {
System.out.println(line);
}
br.close();
}
}
12.IO流-小结
1.流体系
2.流的操作步骤
3.流构造
字节流
InputStream(抽象类)
FileInputStream(String/File)
BufferedInputStream(InputStream) 缓冲流= 基础流+缓冲区
int read()
int read(byte[])
OutputStream(抽象类)
FileOutputStream(String/File)
BufferedOutputStream(OutputStream) 缓冲流= 基础流+缓冲区
write(int)
write(byte[])
write(byte[],index,len)
===============================================================================================
字符流 = 字节流 + 编码表
Reader(抽象类)
FileReader(String/File,Charset.forName("gbk"))默认编码
BufferedReader(Reader)
String readLine():一次读取一行
InputStreamReader(InputStream) : 转换流,把字节流--->字符流
int read() 读取一个字符
int read(char[])读取一个字符数组
Writer(抽象类)
FileWriter(String/File,Charset.forName("utf-8"))
BufferedWriter(Writer)
void newline():写入换行符
OutputStreamWriter(OutputStream) : 转换流
write(int)
write(char[])
write(String)
文件复制
字节流复制(字节,字节数组)
字节缓冲流复制(字节,字节数组)
字符缓冲流复制文本文件,一次一行



