如何防止通过 AutoCloseInputStream 关​​闭 InputStream

How to prevent closing InputStream by AutoCloseInputStream

我想做的是:打开大文件的 InputStream,按 10MB 块读取,上传一个块,读取下一个块。

val chunkCount = Math.ceil(totalSize.toDouble() / chunkSize.toDouble()).toInt()
for (chunkNumber in (0..chunkCount-1)) {
    var chunk = ByteArray(chunkSize)
    val currentChunkSize = inputStream.read(chunk)
    if (chunk.size != currentChunkSize) { //last chunk
        chunk = chunk.copyOf(currentChunkSize)
    }
    // uploading of chunk
}

我为此任务编写了很好的代码,但问题是 ContentResolver returns ParcelFileDescriptor.AutoCloseInputStream 作为 InputStream。这个实现打破了 InputStream 的契约,因为它在第一个 .read() 之后自行关闭,所以当我尝试读取下一个块时,我得到 IOException - "The stream was closed"。

我不想一开始就获取整个数组.read(),因为文件可能很大,这会降低性能或调用 OutOfMemory 错误。

如何防止 AutoCloseInputStream 关​​闭 InputStream,或者使 ContentResolver return 正常 FileInputStream?

已更新

问题不在 AutoCloseInputStream 中,而是在 Android 系统中,如果应用程序内存不足,系统会关闭流。

请不要对它更多的评论投反对票以获取更多信息,但其中包含代码有点长。 我认为 AutoCloseInputStream 仅在到达文件末尾时才关闭 inputStream

要执行块,您需要像这样调用 read 吗?其中 len 是块大小,off 是你最后一个块上传偏移量需要

int read (byte[] b, int off, int len)

class InputStream 的 read(b, off, len) 方法只是重复调用 read() 方法。如果第一个此类调用导致 IOException,则从对 read(b, off, len) 方法的调用返回该异常。如果对 read() 的任何后续调用导致 IOException,则会捕获异常并将其视为文件末尾;到该点为止读取的字节存储到 b 中,并返回异常发生前读取的字节数。

问题不在 AutoCloseInputStream 中,而是在 Android 系统中。它会在内存不足时关闭流。

我通过重新打开流并调用 InputStream.skip(offset: long)

解决了这个问题