ByteArrayOutputStream 对 RAM 内存的极端使用

Extream usage of RAM memory by ByteArrayOutputStream

所以我的问题听起来像这样。我需要制作一个文件的 base64 编码字符串,为此,我使用此方法:

public String getStringFile(File f) {
    InputStream inputStream = null;
    String encodedFile= "", lastVal;
    try {
        inputStream = new FileInputStream(f.getAbsolutePath());

        byte[] buffer = new byte[10240];
        int bytesRead;

        ByteArrayOutputStream output = new ByteArrayOutputStream();
        Base64OutputStream output64 = new Base64OutputStream(output, Base64.DEFAULT);

        while ((bytesRead = inputStream.read(buffer)) != -1) {
            output64.write(buffer, 0, bytesRead);
        }

        output64.close();
        encodedFile =  output.toString();
    } catch (Exception e) {
        e.printStackTrace();
    }

    lastVal = encodedFile;

    return lastVal;
}

问题是,当我尝试对大约 20 Mb 的文件进行编码时(确切的文件大小为 19,35 Mb),我得到了 OutOfMemoryException。

之前:

之后:

我做错了什么,我该如何解决这个问题?提前致谢。

What am I doing wrong

您正在尝试使用 base64 将一个 ~20MB 的文件编码为一个字符串。在许多 Android 设备上,您将没有足够的堆 space 来分配这么大的单个内存。

how can I fix this issue?

如果 "this issue" 是 "create a ~26MB string of base64-encoded data",则没有可靠的方法来执行此操作。无论您试图通过创建这样一个字符串来解决什么问题,您都必须找到其他解决方案。

ByteArrayOutputStream output = new ByteArrayOutputStream();
Base64OutputStream output64 = new Base64OutputStream(output, Base64.DEFAULT);

如果您使用 HttpUrlConnection 自己上传 base64,您可以使用 ByteArrayOutputStream 并在直接上传时将上面的行替换为

OutputStream output = con.getOutputStream();
Base64OutputStream output64 = new Base64OutputStream(output, Base64.DEFAULT);

未测试。

当然你也可以直接base64编码成FileOutputStream

OutputStream output = new FileOutputStream(......);
Base64OutputStream output64 = new Base64OutputStream(output, Base64.DEFAULT);

然后使用 POJO 上传该文件。