10

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

考虑到类的方法只是重复调用该方法InputStream.read(byte[] b),在某种程度上更快吗?read(b, off, len)InputStreamread()

4

2 回答 2

4

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

从 InputStream - read(byte[]) 重复调用 read()。

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

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

   // code removed
}

从 BufferedInputStream - read(byte[]) 不调用 read()。

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
}

从 FileInputStream - read(byte[]) 不调用 read()。

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;

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

注意: read(byte[], int, int) 的实现在所有三种情况下都不同。

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

无论您使用 BufferedInputStream 还是 FileInputStream,一次 read(byte[]) 都会导致最多一次系统调用来读取 byte[]。

于 2012-07-16T10:50:41.927 回答
2

使用您认为对您的情况最方便的任何一种,但请记住InputStreamBufferedInputStream.

read()每次阅读时,如果没有缓冲,单个将命中底层流(例如文件系统)。使用缓冲同样read()会加载一个块(例如 4KiB)并对其进行缓冲。显然从磁盘读取(即使存在一些较低级别的操作系统/硬盘缓存)要慢得多。

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

于 2012-07-16T09:58:18.893 回答