为什么出现字符流

需求:字节流读文本文件数据 由于字节流操作中文不是特别方便,所以Java就提供字符流。字符流=字节流+编码表

用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?如下 汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数

 

为什么出现字符流的练习

 

编码表

基础知识: 1、计算机中存储的信息都是用二进制数表示的。我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果 2、按照某种规则,将字符存储到计算器中,称为编码。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码。这里强调一下:按照 A编码存储,就必须按照A编码解析,这样才显示正确的文本符号,否则就会导致乱码现象 3、字符编码就是一套自然语言的字符与二进制数之间的对应规则,比如A对应的是65

什么是字符集: 1、是一个系统支持的所有字符的结合,包括各个国家文件、标点符号、圆形符号、数字等 2、计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码,常见的字符集有ASCII、GBXXX、Unicode

什么是ASCII字符集:是基于拉丁字母的一套电脑编码系统,主要包括控制字符、可显示字符 基本ASCII字符集:使用7位表示一个字符,共128个字符 扩展ASCII字符集:使用8位表示一个字符,共256个字符

什么是GBXXX字符集,即GB系列的字符集 1、GB2312:简体中文码表。一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就可以表示一个汉字 2、GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,采用双字节编码方案(实际开始中常用) 3、GB18030:最新的中文码表。采用多字节编码,每个汉字可以由1个、2个、4个字节组成

什么是Unicode字符集: 1、为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。它最多使用4个字节的数字来表达每个字母、符号、文件。 其中有三种编码方案,UTF-8、UTF-16、UTF32.最为常用的是UTF-8编码 2、UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用中优先采取的编码(实际开始中常用) 互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。它使用1至4为每个字符编码

编码规则 1、28个US-ASCII字符,只需一个字节编码 2、拉丁文等字符,需要两个字节编码 3、大部分常用中文或非中文字,使用三个字节编码 4、其他极少使用的Unicode辅助字符,使用四字节编码

小结:采用何种规则编码,就要采用对应规则来解码,否则就会出现乱码

 

字符串中的编码解码问题

字符串中的编码,我们需要用到两种方法,如下 byte[] getBytes():使用平台(比如我们这里用的是IDEA平台)的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中。默认编码 byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中。指定编码

字符串中的解码,我们需要用到两种构造方法,如下 String(byte[] bytes):通过使用平台(比如我们这里用的是IDEA平台)的默认字符集解码指定的字节数组来构造新的String String(byte[] bytes,String charsetName:通过指定的字符集解码指定的字节数组来构造新的String

注意:采用何种规则来编码,就要采用对应规则来解码,否则就会出现乱码

 

字符串中编码解码问题的练习

 

字符流中的编码解码问题

字符流抽象基类: 1、Reader:字符输入流的抽象类 2、Writer:字符输出流的抽象类

字符流中和编码解码问题相关的两个类: 1、InputStreamReader。看后缀我们可以判断该类是字符输入流,也就是可以把后缀理解为基类 2、OutputStreamWriter。看后缀我们可以判断该类是字符输出流,也就是可以把后缀理解为基类

InputStreamReader类在java.io包下。该类是具体类,继承自Reader类 该类是从字节流到字符流的桥梁:该类读取字节,并使用指定的charset将其解码为字符,该类可以指定字符集\

OutputStreamWriter类在java.io包下。该类是具体类,继承自Writer类 该类是字符流到字节流的桥梁:使用指定的字符集charset将写入的字符编码为字节,该类可以指定字符集

 

字符流中编码解码问题的练习

 

字符流写数据的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)写一个字符串的一部分
方法名说明
flush()刷新流,还可以继续写数据
close()关闭流,释放资源,但是在关闭之前会主动先刷新流。一旦关闭就不能写数据

 

字符流写数据5种方式的练习

 

字符流读数据的2种方式

方法名说明
int read()一次读一个字符数据
int read(char[] cbuf)一次读一个字符数组数据

 

字符流读数据2种方式的练习

 

字符流复制Java文件

需求:把"D:\huanf\java\src\ch18_ch19储物区\copy.txt"复制到"D:\huanf\java\src\ch18_ch19储物区\JavaSE"里面

思路: 1、根据数据源创建字符输入流对象 2、根据目的地创建字符流输出流对象 3、读写数据,复制文件 4、释放资源

 

字符流复制Java文件的练习

 

字符流复制Java文件改进版

需求:把"D:\huanf\java\src\ch18_ch19储物区\copy2.txt"复制到"D:\huanf\java\src\ch18_ch19储物区\JavaSE"里面

分析: 1、转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化书写,转换流提供了对应的子类 2、InputStreamReader有一个直接子类为FileReader,该子类是具体类,是读取字符文件的便捷类,该子类有3个构造方法,自己文档查查,我们只用FileReader(String fileName),该构造方法的作用是创建一个新的FileReader,给定要读取的文件的名称 3、OutputStreamWriter有一个直接子类为FileWriter,该子类是具体类,是写入字符文件的便捷类,该子类有5个构造方法,自己文档查查,我们只用FileWriter(String fileName),该构造方法的作用是构造一个给定文件名的FileWriter对象 4、当不涉及转换流的编码和解码问题时,我们就可以用新学的FileReader、FileWriter代替InputStreamReader、OutputStreamWriter

思路: 1、根据数据流创建字符输入流对象 2、根据目的地创建字符输出流对象 3、读写数据,复制文件 4、释放资源

 

字符流复制Java文件改进版的练习