day10 IO流——字符流
首先要明确 , 字节流是不能写汉字的!!!!之前看文档的时候都看到了。read和write后面的参数只能是字节数组!!!!所以你就算能写汉字了,也是要先把汉字的字符串什么的, 用geyBytes方法转换成字节数组在再写的!!!
相当于把汉字编码了,然后吧字节数组(都是0101010的数字)传给write的参数。。。。于是才写了。 直接用write(“撒大声地”)才算是直接写。
同样的,在读的时候,也是用String的构造方法String(buf , 0 ,length)进行解码,转换成字符的!!!都是利用了String类当中介,并不能直接读写!!
我要是一个字节一个字节读。。。就会读出一个个数字了。。。如果直接转char,会变成一堆乱七八糟符号。。。因为2个字节才能拼成一个汉字。。
然后了解一下常见码表。。
常见码表:
ASCII:a 97 美国标准信息交换码。用一个字节的7位可以表示。
ISO8859-1: 拉丁码表。欧洲码表,用一个字节的8位表示。又称Latin-1(拉丁编码)或“西欧语言”。ASCII码是包含的仅仅是英文字母,并且没有完全占满256个编码位置,所以它以ASCII为基础,在空置的0xA0-0xFF的范围内,加入192个字母及符号,
藉以供使用变音符号的拉丁字母语言使用。从而支持德文,法文等。因而它依然是一个单字节编码,只是比ASCII更全面。
GB2312: 英文占一个字节,中文占两个字节.中国的中文编码表。
GBK: 中国的中文编码表升级,融合了更多的中文文字符号。
Unicode: 国际标准码规范,融合了多种文字。所有文字都用两个字节来表示,Java语言使用的就是unicode。
UTF-8: 最多用三个字节来表示一个字符。
(我们以后接触最多的是iso8859-1、gbk、utf-8)
用FileOutputStream FileInputStream 默认都是用GBK码表!!!!
也有人想, 2个字节对应一个汉字, 那用2个字节的缓冲数组就好了呀。。。每次就可以读写一个汉字了。开心!!
这个想法很蠢的。。因为这么机械的办法没法判断汉字边界啊。。。如果汉字英文标点符号混在一起不就GG了么。。。sb
那到底咋读写中文呀!!!
引出!!!字符流!!!!!!!
字符流 : 会把读取到的二进制数据进行对应的编码 解码工作!!
—————————Reader 抽象类
———————————FileReader 读取文件的输入字符流
坑的一逼。。没有特有方法,全是继承的方法。
输入字符流
下面这张图是Reader的方法,注意字符流每次读取的都是一个字符,看返回类型!!!是一个int,显然这个字符不管是中文还是英文都放得下!!
还记得字节流的Read吗!!虽然返回值也是int,但是只取后8位一个字节的数据!!!不会都忘了吧!!! 记住!!所以Reader厉害一点啊!!
注意哦。。。也可以直接把读取的数据送到字符数组!!!就不用String转码了喂。。!! 所以可以直接创建缓冲字符数组配合使用啊!!
输出字符流
其实Writer虽然不是缓冲类,但是内部也维护了一个1kb的字符数组!!,固定1kb,不可以指定
如果需要写,则和缓冲类一样要flush。
但是不能读取非文本数据啊。。
还有哦。 用字节流配合缓冲数组读取文本, 配合String的转码功能有时候也会出问题,因为字节流毕竟是按照字节来的 除非你每次都是能一次全放到缓冲数组里面, 如果有一次读到了汉字与英文字母的边界,然后再去转码, 不就炸了吗。想想是不是。
③缓冲输入字符流 BufferedReader
也是维护了8kb的缓冲字符数组
提高了字符流的读取效率, 还拓展了FileReader的功能!!!,所以比缓冲字节流厉害一点。。。。缓冲字节流基本一点用没有。。。嗨呀- - 缓冲字符流是有用的!!!!
其实就是这个readLine功能!!如果到文件末尾,返回null,因为返回值是String!!
其实也不是多难,。。但是方便,下面是自己的实现
public static String myReadLine(FileReader fileReader) throws IOException{
//创建一个字符串缓冲类对象
StringBuilder sb = new StringBuilder(); //StringBuilder主要是用于存储读取到的数据
int content = 0 ;
while((content = fileReader.read())!=-1){
if(content=='\r'){
continue;
}else if(content=='\n'){
break;
}else{
//普通字符
sb.append((char)content);
}
}
//代表已经读取完毕了。
if(content ==-1){
return null;
}
return sb.toString();
}
③缓冲输出字符流 BufferedWriter
很蠢。。。。FileWriter已经维护了一个1kb的缓冲字符数组, 结果这个缓冲字符流又多维护了一个8kb的缓冲字符数组而且还可以指定大小。。。Writer的1kb就是固定的不可以指定啦。
其实就是多了一个newline方法。。。没啥大用。。