gpt4 book ai didi

android - FileChannel.transferFrom 因内存不足错误而无法处理较大的文件

转载 作者:太空狗 更新时间:2023-10-29 16:36:16 35 4
gpt4 key购买 nike

FileChannel.transferFrom(source, 0, source.size()) 在尝试复制大小约为 2GB 的文件时给出以下 OutOfMemory 异常。我了解由于文件较大而导致的内存问题。我们可以通过循环处理小块文件来解决这个问题吗?

01-22 17:27:03.365: W/System.err(28538): java.io.IOException: mmap failed: ENOMEM (Out of memory)
01-22 17:27:03.375: W/System.err(28538): at java.nio.MemoryBlock.mmap(MemoryBlock.java:119)
01-22 17:27:03.375: W/System.err(28538): at java.nio.FileChannelImpl.map(FileChannelImpl.java:249)
01-22 17:27:03.380: W/System.err(28538): at java.nio.FileChannelImpl.transferFrom(FileChannelImpl.java:381)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.util.InSyncIOUtils.copyFile(InSyncIOUtils.java:123)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.getFileItemForFile(ProcessUploadTask.java:102)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.processUploads(ProcessUploadTask.java:124)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.doInBackground(ProcessUploadTask.java:53)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.doInBackground(ProcessUploadTask.java:1)
01-22 17:27:03.380: W/System.err(28538): at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-22 17:27:03.380: W/System.err(28538): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
01-22 17:27:03.380: W/System.err(28538): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
01-22 17:27:03.380: W/System.err(28538): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
01-22 17:27:03.380: W/System.err(28538): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
01-22 17:27:03.380: W/System.err(28538): at java.lang.Thread.run(Thread.java:841)
01-22 17:27:03.385: W/System.err(28538): Caused by: libcore.io.ErrnoException: mmap failed: ENOMEM (Out of memory)

编辑:

我尝试了以下代码:

    for (long n = 0, s = source.size() >> 1; n < s;) {
Log.d("copy file", "inside for loop " + destination.size());
long c = destination.transferFrom(source, n, s - n);
n += c;
Log.d("copy file", "results: c=" + c + ", n=" + n);
}

但它只复制文件的前半部分...

最佳答案

我遇到了与 FileChannel.transferFrom 相同的问题,但我什至偶尔会看到文件小于 512MB 时出现 ENOMEM 错误。

这是我最终用来以较小的 block 传输文件的代码:

  // Transfer file in 256MB blocks
final long blockSize = Math.min(268435456, sourceChannel.size());
long position = 0;
while (destinationChannel.transferFrom(sourceChannel, position, blockSize) > 0) {
position += blockSize;
}

transferFrom 方法返回它成功复制的字节数。如果它返回一个大于零的数字,它复制了整个 block ,所以尝试复制另一个 block 。当它不复制任何内容时,您就完成了。

关于android - FileChannel.transferFrom 因内存不足错误而无法处理较大的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28088408/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com