如何防止AutoCloseInputStream关闭InputStream

时间:2017-04-19 16:33:06

标签: java android inputstream

我想做什么:打开大文件的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将ParcelFileDescriptor.AutoCloseInputStream作为InputStream返回。这个实现破坏了InputStream的契约,因为它在第一个.read()之后自行关闭,所以当我试图读取下一个块时,我得到IOException - “流已关闭”。

我不希望首先获得整个数组.read(),因为文件可能很大,并且会使性能恶化或者可能会调用OutOfMemory错误。

如何防止AutoCloseInputStream关闭InputStream,或者让ContentResolver返回正常的FileInputStream?

已更新

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

2 个答案:

答案 0 :(得分:1)

请不要对其他信息进行更多评论,但有点长的代码。 我以为AutoCloseInputStream只在到达文件末尾时关闭了inputStream

要做块,你需要调用这样的读取吗?其中len是块大小,off是最后一个块上传偏移量需要的位置

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

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

答案 1 :(得分:1)

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

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

来解决它