在介绍FileInputStream 与 BufferedInputStream 两者的区别之前,让我们先了解一下JAVA IO流中最基本的一个抽象基类:InputStream。InputStream就是Java标准库提供的最基本的输入流,它位于java.io这个包里。java.io包提供了所有同步IO的功能。要特别注意的一点是,InputStream并不是一个接口,而是一个抽象类,它是所有输入流的超类。

//输入流

public abstract class InputStream implements Closeable {
    
}

区别:

1.FileInputStream

FileInputStream是InputStream的一个子类。FileInputStream是直接从磁盘文件流中读取数据。

//FileInputStream类部分源码

public
class FileInputStream extends InputStream
{
    
    private final String path;

    private FileChannel channel = null;

    private final Object closeLock = new Object();
    private volatile boolean closed = false;

    
    public FileInputStream(String name) throws FileNotFoundException {
        this(name != null ? new File(name) : null);
    }

    
    public FileInputStream(File file) throws FileNotFoundException {
        String name = (file != null ? file.getPath() : null);
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(name);
        }
        if (name == null) {
            throw new NullPointerException();
        }
        if (file.isInvalid()) {
            throw new FileNotFoundException("Invalid file path");
        }
        fd = new FileDescriptor();
        fd.attach(this);
        path = name;
        open(name);
    }

2.BufferedInputStream

2.1 BufferedInputStream是缓冲输入流。它继承于FilterInputStream。BufferedInputStream的作用是为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持“mark()标记”和“reset()重置方法”。
2.2 BufferedInputStream本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。

//BufferedInputStream部分源码

public
class BufferedInputStream extends FilterInputStream {

    private static int DEFAULT_BUFFER_SIZE = 8192;

    /**
     * The maximum size of array to allocate.
     * Some VMs reserve some header words in an array.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */
    private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;

    /**
     * The internal buffer array where the data is stored. When necessary,
     * it may be replaced by another array of
     * a different size.
     */
    protected volatile byte buf[];  //内部采用byte类型的数组作为缓冲区

2.3 BufferedInputStream的作用是为其它输入流提供缓冲功能。创建BufferedInputStream时,我们会通过它的构造函数指定某个输入流为参数。BufferedInputStream会将该输入流数据分批读取,每次读取一部分到缓冲中;操作完缓冲中的这部分数据之后,再从输入流中读取下一部分的数据。
缓冲中的数据实际上是保存在内存中,而原始数据可能是保存在硬盘或NandFlash等存储介质中;而我们知道,从内存中读取数据的速度比从硬盘读取数据的速度至少快10倍以上。

总结:

1.BufferedInputStream是字节缓冲流,是套在某个其他的InputStream外使用的,起着缓存的功能,用来改善里面InputStream的性能,自己是没有读取文件功能的,而且它自己不能脱离里面的InputStream单独存在。

2.FileInputStream是字节流,读取一个文件来作InputStream。可以把BufferedInputStream套在FileInputStream外,来改善FileInputStream的性能。

3.使用BufferedInputStream读资源比FileInputStream读取资源的效率高(BufferedInputStream的read方法会读取尽可能多的字节),且FileInputStream对象的read方法会出现阻塞.