【问题标题】:Getting Out Of Memory Error when saving big files保存大文件时出现内存不足错误
【发布时间】:2021-04-23 23:47:42
【问题描述】:

我正在尝试使用此方法将另一个应用程序获取的文件保存到后台线程的内部目录中:

 public static File saveUri(Uri uri,File file, WeakReference<Context> contextWeakReference) throws IOException {

        ContentResolver resolver=contextWeakReference.get().getContentResolver();

        InputStream inputStream=resolver.openInputStream(uri);
        ByteArrayOutputStream stream=new ByteArrayOutputStream();

        FileOutputStream fileOutputStream=new FileOutputStream(file);

        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            stream.write(buffer, 0, bytesRead);
        }
        

        fileOutputStream.write(stream.toByteArray());
        fileOutputStream.close();
        inputStream.close();
        return file ;

    }

它可以工作,直到我保存 100 MB 大小的文件。在此之上,它给出了:

java.lang.OutOfMemoryError: Failed to allocate a 134217744 byte allocation with 25165824 free bytes and 124MB until OOM, max allowed footprint 95471864, growth limit 201326592

在这一行:

stream.write(buffer, 0, bytesRead);

这是我用于后台处理的:

public static final ExecutorService databaseWriteExecutor =
        Executors.newSingleThreadExecutor();

我应该怎么做才能保存大文件而不导致内存不足错误。

【问题讨论】:

    标签: java android file memory


    【解决方案1】:

    未测试,但您可能希望将字节附加到 FileOutputStream 并在循环中写入缓冲区:

    public static File saveUri(Uri uri, File file, ContentResolver resolver) {
        try (final OutputStream os = new FileOutputStream(file, true)) {
            final InputStream inputStream = resolver.openInputStream(uri);
            if (inputStream != null) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
                inputStream.close();
            }
        } catch (IOException e) {
            Log.e(TAG, "Error writing file");
        }
        return file;
    }
    

    有很多方法可以做到这一点......

    【讨论】:

      【解决方案2】:

      当您从 inputStream 读取数据时,您并未写入 FileOutputStream,而是将内存中的所有内容保存在 stream 变量上。

      请链接两个流,这样您正在复制的文件的内容就不会留在内存中

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-14
        • 2014-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-03
        • 2019-08-23
        相关资源
        最近更新 更多