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

时间:2012-07-16 09:55:03

标签: java inputstream

我正在尝试比较InputStream.read()InputStream.read(byte[] b)的效果。

InputStream.read(byte[] b)在某种程度上更快,因为课程read(b, off, len)的{​​{1}}方法只是反复调用方法InputStream

2 个答案:

答案 0 :(得分: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次......现在阅读一次性使用20个字节的数组,即使用read(byte [] 20),现在这将打击基础流(例如文件系统)一次或20次.. ?? (因为它给出:read(byte [] b)方法也会重复调用方法read()20次)??

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

答案 1 :(得分:2)

使用您认为最方便的案件,但请记住用InputStream包裹BufferedInputStream

如果没有缓冲,单个read()将在每次阅读时点击基础流(例如文件系统)。缓冲相同的read()加载一个块(例如4KiB)并缓冲它。显然从磁盘读取(即使存在一些低杠杆OS /硬盘缓存)要慢得多。

因此read(byte[] b)只有在您的流未缓冲时才更好 - 或者您真的想要读取多个字节。