字节输入输出流总结 FileInputStream FileOutputStream

字节流总结:

1. 判断使用输入流还是输出流的依据

  • 以当前程序(也就是内存)为参照物,从硬盘向内存中读取数据,使用输入流 FileInputStream。从内存向硬盘写出数据,使用输出流 FileOutputStream。

字节输入输出流总结 FileInputStream FileOutputStream

2. FileInputStream 读取文件

    使用FIleInputStream读取文件时,我们通常维护一个缓冲数组来提高读取效率。假如我们维护的这个缓冲字节数组的长度是5,而我们读取的文件内数据的长度是8。那么当我们使用 new String() 来构建字符串时,它是怎么读取的呢?

    使用缓冲数组读取文件内容,然后构建字符串,有两种情况,第一种是覆盖式的读取,第二种是先清空再填充。两种方式如下图:

字节输入输出流总结 FileInputStream FileOutputStream

3. BufferedInputStream 读取效率比 FileInputStream 高的原因?

     BufferedInputStream 的类内部,维护了一个缓存数组。但是它不具备读文件的功能,需要依赖 FileInputStream 的read()方法将文件中的数据读取到内存中,BufferedInputStream 在类的内部维护了一个 8kb的数组,FileInputStream 的 read() 方法将硬盘中的数据读取到这个缓存数组中,然后 BufferedInputStream才能使用 read() 方法从这个数组中读取数据。

    BufferedInputStream 每次读取一个字节的数据,而 FileInputStream 每次也读取一个字节的数据,那么为什么 BufferedInputStream 读取效率要高于 FileInputStream呢?

    看段源码比较一下

字节输入输出流总结 FileInputStream FileOutputStream

通过源码我们可以看出:

      FileInputStream每次读取完一个字节,就传输一个字节,这消耗了大量的传输时间。

      而 BufferedInputStream,每次读取一个字节,然后将这个字节放入缓存数组中,当读取了8kb的数据或者没有数据可读时,会一次性传输一个数组长度(即8kb)的数据,这样节省了大量的传输时间。

    因此可以得出结论,BufferedInputStream 读取数据的效率比 FileInputStream 读取数据的效率要高的多。

 

既然BufferedInputStream 的工作效率要比 FileInputStream 读取数据的工作效率高的多,那么我们是不是以后再工作中要是用 BufferedInputStream来进行硬盘与内存之间的数据传输呢?

    在使用 FileInputStream读取文件数据时,我们并没有一个字节一个字节的去读取文件,而是经常会自己去维护一个缓存字节数组,这个数组的大小是1024的倍数。而BufferedInputStream 内部也是维护了一个长度为 8192 字节(即8kb大小)的缓存数组。BufferedInputStream 的缓冲数组大小是固定的,而我们自己维护的缓存数组的大小是可变的,更具有灵活性。

    使用FileInputStream 可以直接读取文件数据内容,而 BufferedInputStream 需要借助FileInputStream 的 read()方法先将文件内容读取到缓存数组中,再使用 BufferedInputStream 的 read() 方法读取缓存数组中的数据,通过源码我们也能看出来,BufferedInputStream 的 read() 方法在读取缓存数组中的数据时,每次读取读需要进行 if判断,这样浪费了大量的时间,理想上来说,使用缓冲数组的 FileInputStream的工作效率要高于 BufferedInputStream的工作效率。

所以从习惯上或者理想状态来讲,个人都比较推荐使用 FileInputStream。

如有错误处,欢迎大佬进行指正。