Java 一次读取单个字节与多个字节时的性能?

Java 一次读取单个字节与多个字节时的性能?,java,inputstream,Java,Inputstream,我试图在性能方面比较InputStream.read()vsInputStream.read(byte[]b) IsInputStream.read(byte[]b)在某种程度上更快,因为类InputStream的read(b,off,len)方法只调用方法read()重复使用?使用您认为最方便的方法,但请记住使用缓冲输入流包装您的输入流 如果不进行缓冲,每次读取时,read()都会命中底层流(例如文件系统)。通过缓冲相同的read()加载块(例如4KiB)并对其进行缓冲。显然,从磁盘读取(即使

我试图在性能方面比较
InputStream.read()
vs
InputStream.read(byte[]b)


Is
InputStream.read(byte[]b)
在某种程度上更快,因为类
InputStream的
read(b,off,len)
方法只调用方法
read()
重复使用?

使用您认为最方便的方法,但请记住使用
缓冲输入流
包装您的
输入流

如果不进行缓冲,每次读取时,
read()
都会命中底层流(例如文件系统)。通过缓冲相同的
read()
加载块(例如4KiB)并对其进行缓冲。显然,从磁盘读取(即使存在较低级别的操作系统/硬盘缓存)的速度要慢得多


因此,
read(byte[]b)
只有在您的流没有缓冲的情况下,或者如果您真的想读取多个字节时才更好。

您不应该混淆InputStream的默认行为和它的大多数子类的功能。OO设计的一个原则是,子类可以改变实现方法的行为

从InputStream-read(字节[])重复调用read()

public int read(byte b[], int off, int len) throws IOException {
   // code removed

        for (; i < len ; i++) {
            c = read();

   // code removed
}
从FileInputStream-read(字节[])不调用read()

虽然InputStream一次读取一个字节,但几乎所有的实现都会将读取(byte[])传递给底层流中的相同方法

注意:读取(byte[],int,int)的实现在这三种情况下都是不同的

我想更清楚地问的是:假设我想读取20个字节,每次读取一个字节将在循环中命中底层流(例如文件系统),这意味着20次。好的,现在一次读取20个字节的数组,即使用read(byte[]20),现在它将命中底层流(例如文件系统)一次或20次。。??(正如所给出的:read(byte[]b)方法也将重复调用read()方法20次)


无论您使用BufferedInputStream还是FileInputStream,一次读取(字节[])都会导致atmost一次系统调用来读取字节[]。

一次读取一个字符/字节(即InputStream.read()),或者一次读取一个字节/字符数组一个块。.读取(字节[]b)方法也将调用方法read()有什么区别重复字节/字符数组块声明次数?@Tomasz Nurkiewicz:谢谢,但不包括BufferedInputStream的情况。如果我们只讨论InputStream..那么两种方法都会产生相同的性能..这是真的吗?@AshishKataria你只是在重复原来的问题,他已经回答了。如果您插入一个
BufferedInputStream,
操作中没有单字节读取操作,这就是它的目的。@EJP..谢谢,但是忘记BufferedInputStream的一个例子:我想更清楚地问的是:假设我想读取20个字节,一次读取一个字节将命中底层流(例如,文件系统)每次在循环中,这意味着20次..好的,现在一次读取20个字节的数组,即使用read(byte[]20),现在它将击中底层流(例如,文件系统)一次或20次..???(正如给定的:read(byte[]b)方法也将重复调用read()方法20次)??@AshishKataria您引用的是一个抽象类。请引用一个不会覆盖该方法的具体实现类。彼得拉维:感谢您的出色解释。那么这是否意味着InputStream的所有3个方法都将一次读取atmost一个字节,而不管我们在读取中指定的字节数(字节[])??不,我正试图详细说明为什么不是这样。我不清楚你为什么会认为是这样。还有一件事,如果使用BufferedInputStream,那么创建字节缓冲区并使用读取(byte[])进行读取有什么好处方法,而不是逐字节读取它?优势要小得多。使用read(byte[])仍然可以稍微快一点,因为这样调用BufferedInputStream的频率会降低。注意:如果您正在读取16KB或更大的缓冲区,则使用BufferedInputStream可能没有帮助(如果其缓冲区更小)Peter Lawrey非常感谢,BufferedInputStream在简单的read()方法调用中是否使用或保留了任何dafault缓冲区大小,或者说它在内部构建了数据大小,我的意思是不显式指定缓冲区大小。
public synchronized int read(byte b[], int off, int len) throws IOException {
   // code removed
        int nread = read1(b, off + n, len - n);
   // code removed
}

private int read1(byte[] b, int off, int len) throws IOException {
   // code removed
            return getInIfOpen().read(b, off, len);
   // code removed
}
public int read(byte b[], int off, int len) throws IOException {
    return readBytes(b, off, len);
}

private native int readBytes(byte b[], int off, int len) throws IOException;