在另两篇文章里讲了 FileReader 和他舅 FileInputStream,一个是从文件中读取字符,一个是从文件中读取字节,那 FileReader 的爸爸 InputStreamReader 干嘛呢?
- java.lang.Object
-
- java.io.Reader
-
- java.io.InputStreamReader
FileReader 是 InputStreamReader 的子类,从级别上来说,InputStreamReader 才是 FileInputStream的兄弟,哈哈。那这个大兄弟到底能干啥?如果我们都是在同一个语言环境里,同一个字符集下,我们就完全没有必要考虑 InputStreamReader 了,但是往往事情都是复杂的。
一天,隔壁老王给了你一个小视频,你满心欢喜回家打开看看,发现播放的全是马赛克,心中一万个神兽跑过吧,怎办?转换字符集呗!这时候就是 InputStreamReader 登场了,他能从字节流里按照你的字符集要求转成字符,就这么神奇。
先看看他的构造函数,有4种:
InputStreamReader(InputStream in)
InputStreamReader(InputStream in, Charset cs)
InputStreamReader(InputStream in, CharsetDecoder dec)
InputStreamReader(InputStream in, String charsetName)
这个InputStream是谁?我们之前介绍过的 【FileInputStream】有印象吗?
所以实例化对象就可以这样写:
new InputStreamReader(new FileInputStream(file)); 这使用了系统默认的字符集,一般中文系统字符集都是GBK或者GB2312吧,但是其他国家有用UTF-8的,当你拿到utf-8的文件,你用系统默认的GBK可能读取的字符就会有问题。这个时候可以在构造函数里指定字符集啦:
new InputStreamReader(new FileInputStream(file), "utf-8");
如果这样使用就是不停的往内存里读取文件内容,如果文件好大,比如高清蓝光10几个G,并发一起读取,很容易干崩服务器呀,怎么办?为了更有效率,也能更好的节省服务器内存,一般情况都是读取文件一部分内容就处理一下,然后再读取一部分,每次读取相同大小的文件内容放到缓冲区里。这样缓冲区的内容被处理后,就抛弃掉,再读进来新的数据继续处理,避免了内存不够的问题,也节省了IO的操作成本。
那怎么缓冲呢?这时候,他的大兄弟,亲兄弟哦,BufferedReader 来了哦:
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
BufferedReader 有个 read() read(char[]) readLine()三个方法,下次讲解。