我正在尝试比较InputStream.read()
与InputStream.read(byte[] b)
的效果。
InputStream.read(byte[] b)
在某种程度上更快,因为课程read(b, off, len)
的{{1}}方法只是反复调用方法InputStream
?
答案 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)
只有在您的流未缓冲时才更好 - 或者您真的想要读取多个字节。