最近在学习java中的字节流和字符流,而又有转换流,为什么还要有转换流呢?首先先来看一下字节流和字符流。
字节流:
读取操作: InputStream(子类FileInputStream)------read()
可用BufferedInputStream提高效率(缓冲字节流)
写入操作:OutputStream(子类FileOutputStream)---write()
可用BufferedOutputStream提高效率(缓冲字节流)
字符流:
读取操作:Reader(InputStreamReader、FileReader)--------read()
可用BufferedReader提高效率(缓冲字节流)
写入操作:Writer(OutputStreamWriter、FileWriter)---------write()
可用BufferedWriter提高效率(缓冲字节流)
正常情况下,我们用字节流可以对所有的数据进行操作,但是有些时候我们在处理一些文本时我们要用到字符流,比如,查看文本中的中文时就是需要采用字符流,更为方便。如,在记事本中输入“中国”两个汉字,存储格式为“UTF-8”,通过字节流方式读取,读到的内容我们看不懂。
由此看出,通过字节流很难得到我们能看的懂得文本内容,换句话说也就是很难正确解码。
我们用字节数组,并通过字符串设定编码格式来显示内容,此时得到的使我们能看得懂的内容,但是a.txt中的内容较少,当较多时,而在1024的整倍数处又会出现解码不正确的问题,字节数组长度无法根据解码内容自动设定,此时就需要转换流来完成解码任务。
所谓的解码,实际上就是将我们看不懂的数据格式(按照一定的规则,编码表)转换成我们能够看得懂的内容,即,二进制数据------字符;对应的编码就是将看得懂的转换成看不懂的,字符-----二进制数据。
所以,字符流 = 字节流 + 编码表
下面的是一些常见的编码表的介绍:
计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字。就将各个国家的文字用数字来表示,并一一对应,形成一张表。
ASCII:美国标准信息交换码。
用一个字节的7位可以表示。
ISO8859-1:拉丁码表。欧洲码表
用一个字节的8位表示。
GB2312:中国的中文编码表。
GBK:中国的中文编码表升级,融合了更多的中文文字符号。
GB18030:GBK的取代版本
BIG-5码:通行于台湾、香港地区的一个繁体字编码方案,俗称“大五码”。
Unicode:国际标准码,融合了多种文字。
所有文字都用两个字节来表示,Java语言使用的就是unicode
UTF-8:最多用三个字节来表示一个字符。
UTF-8不同,它定义了一种“区间规则”,这种规则可以和ASCII编码保持最大程度的兼容:
它将Unicode编码为00000000-0000007F的字符,用单个字节来表示
它将Unicode编码为00000080-000007FF的字符用两个字节表示
它将Unicode编码为00000800-0000FFFF的字符用3字节表示
转换流中,InputStreamReader和OutputStreamWriter是字节流和字符流转换的桥梁,那什么时候使用呢 ?
1.当字节和符之间有转换动作时 2。流操作的数据需要进行编码表指定时。
以读取操作为例:采用转换流在此读取上面的文本InputStreamReader(InputStream is):用默认的编码读取数据;InputStreamReader(InputStream is,StringcharsetName):用指定的编码读取数据
咦,采用了转换流读取了,怎么还是看不懂?InputStreamReader(InputStream is):用默认的编码读取数据;在Eclipse下,默认的编码格式是系统系统的编码格式:GBK,并没有对应上a.txt所采用的编码格式;需要手动指定编码格式InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据
这次就正确了,当然读取的方式还有其他的read方法,可以参照JDk查看,还有写入数据时的编码
OutputStreamWriter(OutputStream os):默认编码写数据,GBK
OutputStreamWriter(OutputStream os,StringcharsetName):指定编码写数据
要想不出现编码与解码的问题,就要保证编码时和解码时采用相同的编码表,而对于一般的本地操作常用的是FileWriter和FilewReader两个类,操作更为方便,采用默认的编码表,,一旦需要自己设定编码格式,就需要采用InputStreamReader,OutputStreamWriter。