Java中的字节流、缓冲流
一、Java中流的分类
1.字符流
Reader Writer
字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节, 操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好。
2.字节流
InputStream OutputStream
字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串。
PS:
InputStream OutputStream是所有二进制流的父类。
他的子类有:
字节流 FileInputStream和FileOutputStream
缓冲流 BufferedInputStream和BufferedOutputStream
数据流 DataInputStream和DataOutputStream
对象流 ObjectInputStream和ObjectOutputStream
流
输入流:将外部的数据读取到程序中
输出流:将数据从程序中写入到文件或者数据库中(持久化)
二、字节流与缓冲流的区别
当程序发出指令去读取一个文件时,对比使用字节流和缓冲流的区别:
字节流:程序——JVM——OS——磁盘文件A——OS——JVM——程序,同理写入到其他文件中去(但每次只读一个字节)
缓冲流:与字节流不同的是JVM会开辟一个缓冲区,将每次读取的字节先存到缓冲区中,当缓冲区存满时再将缓冲区中的内容写入到其他文件中,当缓冲区没有存满时,不会写入。
假设一个文件有1122个字节,缓冲区大小为100个字节,那么要读取12次,最后一次只有22个字节,但此时缓冲区并没有存满,不能将存储的内容从缓冲区中取出。这时我们可以调用缓冲流自带的一个方法flush(强制写入)将最后一次读取的内容强制写入到文件中去。
三、关于缓冲流的使用
在使用字节流时我们可以直接实例化一个对象,例如:FileInputStream fis = new FileInputStream(这里输入一个文件路径);
而缓冲流它必须用字节流来实例化,例如:BufferedInputStream bis = new BufferedInputStream(new FileInputStream(这里输入一个文件路径));
四、字节流与字符流的效率对比
当读取一个较小的文件时,字节流与缓冲流效率差别不大
但当我们读取一个较大的文件时,通过实验对比发现缓冲流明显比字节流快得多。
【对时间效率差异的解释】
BufferedInputStream比FileInputStream多了一个缓冲区,执行read时先从缓冲区读取,当缓冲区数据读完时再把缓冲区填满。
因此,当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高。
BufferedInputStream的默认缓冲区大小是8192字节。当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了。
BufferedOutputStream和FileOutputStream同理,差异更明显一些。