在Android N设备上测试我的应用程序时,我发现我有许多与我使用BufferedInputStream的方式相关的新问题。问题似乎是我如何解释BufferedInputStream.read()的返回值。如果返回0,则假定有0个字节可以从底层流中读取,如果返回-1,则假定底层流已到达文件的末尾(并已退出读取)。这工作很好,直到牛轧糖。现在,当底层InputStream.read()返回0时,BufferedInputStream.read()返回-1。正确的行为是什么?为什么这种情况发生了变化?
下面是一个精炼的例子…
class ZeroBytesReadInputStream extends InputStream {
...
@Override
public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
return 0;
}
}
private int testZeroBytesReadBufferedInputStream() {
InputStream inputStream = new ZeroBytesReadInputStream();
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
int valueReturned = 0;
try {
byte[] toStream = new byte[100];
valueReturned = bufferedInputStream.read(toStream, 0, 100);
Log.d("Zero Bytes Read Test", "BufferedInputStream returned = " + valueReturned + ". Android Version = " + android.os.Build.VERSION.SDK_INT);
} catch (IOException e) {
e.printStackTrace();
}
return valueReturned;
}
运行时的输出10-19 09:28:51.970 9138 9138 D Zero Bytes Read Test: BufferedInputStream returned = -1. Android Version = 24
10-19 09:32:19.200 12675 12675 D Zero Bytes Read Test: BufferedInputStream returned = 0. Android Version = 23
根据InputStream的文档。read(byte[] b, int off, int len),该方法实际上不应该返回0,除非len
参数为0:
此方法阻塞,直到输入数据可用,文件结束检测到,或抛出异常。
如果len为0,则不读取任何字节并返回0;否则,试图读取至少一个字节。如果没有可用的字节由于流位于文件末尾,因此返回值-1;否则,至少读取一个字节并存储在b中。
因此,底层的流实现是有bug的,因此BufferedInputStream
的行为是不确定的。