为什么BufferedInputStream.read()在Android牛轧糖中返回-1,而它通常返回0 ?



在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的行为是不确定的。

最新更新