Java 超详细讲解字符流
一、字符流的由来
由于使用字节流操控中文时不是很方便,Java就提供了字符流来进行操控中文
实现原理:字节流+编码表
为什么用字节流进行复制带有中文的文本文件时没有问题?
因为底层操作会自动进行字节拼接成中文
怎样识别该字节是中文呢?
汉字在存储时,无论是UTF-8还是GBK,第一个字节都是负数用来提示
二、编码表
字符集:
是一个系统支持的所有字符的集合,包括国家文字、标点符号、图形符号、数字等
计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码
常见的字符集有ASCII字符集、GBXXX字符集、Unicode字符集等
GBK:最常用的中文码表,是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等
GB18030:最新的中文码表,收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国少数民族的文字,同时支持繁体汉字以及日韩汉字等
Unicode字符集:
为了表达任意语言的任意字符而设计,是业界的一个标准,也称为统一码、标准万国码;它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案:UTF-8、UTF-16、UTF32,最常用的是UTF-8
UTF-8:可以用来表示Unicode标准中的任意字符,它是电子邮件、网页及其他存储或传送文件的应用中,优先采用的编码。互联网工作小组要求所有的互联网协议都必须支持UTF-8编码格式。它使用一至四个字节为每个字符编码
UTF-8编码规则:
128个US-ASCII字符,只需要一个字节编码
拉丁文等字符,需要两个字节编码
大部分常用字(含中文),使用三个字节编码
其他极少使用的UniCode辅助字符,使用四个字节编码
总结:编码时使用那种规则,解码就需要采用对应的规则,否则会乱码
三、字符串中的编码解码问题
编码方法(IDEA):
byte[] getBytes():使用平台默认的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
解码方法(IDEA):
String(byte[]bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的String
String(byte[]bytes,String charsetName):通过指定的字符集解码指定的字节数组来构造新的String
IDEA中默认的编码格式是UTF-8
四、字符流的编码解码问题
字符流抽象基类:
Reader:字符输入流的抽象类
Writer:字符输出流的抽象类
字符流中和编码解码问题相关的两个类:
InputStreamReader:是从字节流到字符流的桥梁:它读取字节,并使用指定的字符集将其解码为字符。它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
构造方法:
InputStreamReader(InputStream in) | 创建一个使用默认字符集的InputStreamReader。 |
InputStreamReader(InputStream in, String charsetName) | 创建一个使用命名字符集的InputStreamReader。 |
OutputStreamWruter:是从字符流到字节流的桥梁:使用自订的字符集将写入的字符编码为字节,它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
构造方法:
OutputStreamWriter(OutputStream out) | 创建一个使用默认字符编码的OutputStreamWriter。 |
OutputStreamWriter(OutputStream out, String charsetName) | 创建一个使用命名字符集的OutputStreamWriter。 |
public class ConversionStreamDemo { public static void main(String[] args) throws IOException { //创建一个默认编码格式的InputStreamReader\OutputStreamWriter InputStreamReader ipsr = new InputStreamReader(new FileInputStream("E:\\abc.txt")); OutputStreamWriter opsw = new OutputStreamWriter(new FileOutputStream("E:\\abc.txt")); //写入数据 opsw.write("你好啊"); opsw.close(); //读数据,方式一:一次读取一个字节数据 int ch; while ((ch = ipsr.read()) != -1) { System.out.print((char) ch); } ipsr.close(); } }
四、字符流写数据的五种方法
方法名 | 说明 |
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();
前三个方法与字节流写入方法使用相同,这里重点介绍下面两种方式
public class OutputStreamWriterDemo { public static void main(String[] args) throws IOException { //创建一个默认编码格式的OutputStreamWriter对象 OutputStreamWriter opsw=new OutputStreamWriter(new FileOutputStream("E:\\abc.txt")); //方式一:写入一个字节 opsw.write(97); opsw.flush();//如果需要在文件中立即显示输入的数据,就需要加入刷新方法 //方式二:写入一个字符数组 char[]ch={'a','b','c','二'}; opsw.write(ch); opsw.flush();//如果需要在文件中立即显示输入的数据,就需要加入刷新方法 //方式三:写入一个字符数组的一部分 opsw.write(ch,0,2); opsw.flush();//如果需要在文件中立即显示输入的数据,就需要加入刷新方法 //方式四:写入一个字符串 opsw.write("一二三"); opsw.flush();//如果需要在文件中立即显示输入的数据,就需要加入刷新方法 //方式五:写入一个字符串的一部分 opsw.write("三四五",1,2); opsw.flush();//如果需要在文件中立即显示输入的数据,就需要加入刷新方法 } }
五、字符流读数据的两种方法
方法名 | 说明 |
int read() | 一次读取一个字符数据 |
int read(char[] cbuf) | 一次读取一个字符数组数据 |
public class InputStreamReadDemo { public static void main(String[] args) throws IOException { //创建一个默认编码格式的InputStreamReader InputStreamReader ipsr=new InputStreamReader(new FileInputStream("E:\\abc.txt")); //读取数据,方式一一次读取一个字符数据 int ch; while ((ch=ipsr.read())!=-1){ System.out.print((char) ch); } ipsr.close(); //方式二:一次读取一个字符数组数据 char []ch=new char[1024]; int len; while ((len=ipsr.read(ch))!=-1){ System.out.print(new String(ch,0,len)); } ipsr.close(); } }
小结:如果使用默认编码格式的话,那么字符输入流InputStreamReader可以使用子类FileReader来替代,字符输出流OutputStreamWriter可以使用其子类FileWriter来替代,两者在使用默认编码格式的情况下作用一致。
到此这篇关于Java 超详细讲解字符流的文章就介绍到这了,更多相关Java 字符流内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
原文出处:https://www.cnblogs.com/CYan521/p/16113802.html
相关文章
- 这篇文章主要介绍了如何利用java语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
java 运行报错has been compiled by a more recent version of the Java Runtime
java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01- 这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
- 这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
- 说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
- 这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
- 这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
java 画pdf用itext调整表格宽度、自定义各个列宽的方法
这篇文章主要介绍了java 画pdf用itext调整表格宽度、自定义各个列宽的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-31- 这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
- 这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
- 这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
Java使用ScriptEngine动态执行代码(附Java几种动态执行代码比较)
这篇文章主要介绍了Java使用ScriptEngine动态执行代码,并且分享Java几种动态执行代码比较,需要的朋友可以参考下...2021-04-15- 这篇文章主要介绍了Java开发实现人机猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-03
- 这篇文章主要介绍了Java List集合返回值去掉中括号('[ ]')的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-29
Java 8 Stream 的终极技巧——Collectors 功能与操作方法详解
这篇文章主要介绍了Java 8 Stream Collectors 功能与操作方法,结合实例形式详细分析了Java 8 Stream Collectors 功能、操作方法及相关注意事项,需要的朋友可以参考下...2020-05-20Java中lombok的@Builder注解的解析与简单使用详解
这篇文章主要介绍了Java中lombok的@Builder注解的解析与简单使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-06- 下面小编就为大家带来一篇java中String类型变量的赋值问题介绍。小编觉得挺不错的。现在分享给大家,给大家一个参考。...2016-03-28
- 这篇文章主要介绍了Java线程池中的各个参数如何合理设置操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-19
- 这篇文章主要介绍了详解Java后端优雅验证参数合法性,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-18