我想做的是:打开大文件的InputStream,用10 it的块读取它,上传一个块,读取下一个块。
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错误。
如何防止InputStream被AutoCloseInputStream关闭,或使ContentResolver返回正常的FileInputStream?
更新
问题不在AutoCloseInputStream中,而是在安卓系统中,如果应用程序内存不足,就会关闭流。
发布于 2017-04-19 15:18:28
问题不在于AutoCloseInputStream,而在于安卓系统。当内存不足时,它会关闭流。
我只是通过重新打开流并调用InputStream.skip(偏移量: long)来解析它。
发布于 2017-04-19 08:58:31
请不要否决它更多的评论,以获得更多的信息,但有点长与代码在其中。我以为AutoCloseInputStream只有在文件结束时才关闭inputStream
你需要这样打电话给read吗?len是块大小,off是上一次块上传偏移量需要的位置。
int read (byte[] b, int off, int len)
类InputStream的read(b,off,len)方法只是重复调用方法read()。如果第一个这样的调用产生一个IOException,则从对read(b,off,len)方法的调用中返回该异常。如果对read()的任何后续调用都会导致IOException,则会捕获该异常并将其视为文件结束;读取到此点的字节被存储到b中,并返回异常发生前读取的字节数。
https://stackoverflow.com/questions/43501341
复制