1.字符流-编码表
- 是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
- 计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBXXX字符集、Unicode字符集等
- 常见的字符集
- 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)
- 支持读取中文
3.字符流-编码和解码的方法
方法名 | 说明 |
---|
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();
byte[] bys2 = s.getBytes("UTF-8");
byte[] bys3 = s.getBytes("GBK");
System.out.println(Arrays.toString(bys1));
System.out.println(Arrays.toString(bys2));
System.out.println(Arrays.toString(bys3));
String ss = new String(bys3,"GBK");
System.out.println(ss);
}
}
4.字节流读取中文出现乱码的原因
字节与中文字符不是一一对应的关系!
5.字符流-读取中文的过程
由于字节流操作 中文 不是特别的方便,所以Java就提供字符流
字符流 = 字节流 + 编码表 !
6.字符流-写出数据
- 介绍
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");
char[] chs = {'a', 'b', 'c', 'd', 'e'};
fw.write("abcde", 1, 3);
fw.write(System.lineSeparator());
fw.close();
}
}
7.字符流-写出数据的注意事项
8.字符流-flush和close方法
- flush(): 刷新流(发送缓冲区中的内容到目标文件) ,流还可以继续使用!
- close(): 1.会先刷新流,再关闭 , 关闭后,流不能再使用!
9.字符流-读取数据
介绍
- 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");
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 bw = new BufferedWriter(new FileWriter("myCharStream\\bw.txt"));
bw.write("hello\r\n");
bw.write("world\r\n");
bw.close();
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\bw.txt"));
char[] chs = new char[1024];
int len;
while ((len=br.read(chs))!=-1) {
System.out.print(new String(chs,0,len));
}
br.close();
}
}
11.缓冲流-特有方法
方法名 | 说明 |
---|
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.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)
文件复制
字节流复制(字节,字节数组)
字节缓冲流复制(字节,字节数组)
字符缓冲流复制文本文件,一次一行