【发布时间】:2012-07-15 03:57:08
【问题描述】:
我正在尝试比较 InputStream.read() 和 InputStream.read(byte[] b) 的性能。
考虑到InputStream 类的read(b, off, len) 方法只是重复调用read() 方法,InputStream.read(byte[] b) 在某种程度上更快吗?
【问题讨论】:
标签: java inputstream
我正在尝试比较 InputStream.read() 和 InputStream.read(byte[] b) 的性能。
考虑到InputStream 类的read(b, off, len) 方法只是重复调用read() 方法,InputStream.read(byte[] b) 在某种程度上更快吗?
【问题讨论】:
标签: java inputstream
您不应混淆 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[]。
【讨论】:
使用您认为最方便的方式,但请记住将您的 InputStream 包装为 BufferedInputStream。
如果没有缓冲单个 read() 将在您每次阅读时访问底层流(例如文件系统)。通过缓冲相同的 read() 加载一个块(例如 4KiB)并对其进行缓冲。显然从磁盘读取(即使存在一些较低级别的操作系统/硬盘缓存)要慢得多。
因此,read(byte[] b) 仅在您的流未缓冲或您确实想读取多个字节时更好。
【讨论】:
BufferedInputStream,,则该操作中没有单字节读取操作,这就是它的用途。