我想做什么:打开大文件的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系统中,如果应用程序内存不足,则会关闭流。
答案 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)
来解决它