在 Android 上以 Base64 格式转换文件 (<100Mo)

Convert a file (<100Mo) in Base64 on Android

我正在尝试将文件从 sdcard 转换为 Base64,但似乎文件太大,我收到 OutOfMemoryError。

这是我的代码:

InputStream inputStream = null;//You can get an inputStream using any IO API
inputStream = new FileInputStream(file.getAbsolutePath());
byte[] bytes;
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        output.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    e.printStackTrace();
}
bytes = output.toByteArray();
attachedFile = Base64.encodeToString(bytes, Base64.DEFAULT);

有没有办法在归档 String attachedFile 时绕过 OutOfMemoryError?

Base64 编码需要 3 个输入字节并将它们转换为 4 个字节。因此,如果您有 100 Mb 的文件,在 Base64 中最终将达到 133 Mb。当您将它转换为 Java 字符串 (UTF-16) 时,它的大小将加倍。更不用说在转换过程中的某个时刻,您会在内存中保存多个副本。无论你如何转动它,它都很难起作用。

这是使用 Base64OutputStream 稍微优化的代码,需要的内存比您的代码少,但我不会屏住呼吸。我的建议是通过跳过到字符串的转换并使用临时文件流作为输出而不是 ByteArrayOutputStream.

来进一步改进该代码
InputStream inputStream = null;//You can get an inputStream using any IO API
inputStream = new FileInputStream(file.getAbsolutePath());
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
Base64OutputStream output64 = new Base64OutputStream(output, Base64.DEFAULT);
try {
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        output64.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    e.printStackTrace();
}
output64.close();

attachedFile = output.toString();
// Converting File to Base64.encode String type using Method
public String getStringFile(File f) {
    InputStream inputStream = null;
    String encodedFile = "", lastVal;
    try {
        inputStream = new FileInputStream(f.getAbsolutePath());

        byte[] buffer = new byte[10240]; //specify the size to allow
        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 (FileNotFoundException e1) {
        e1.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    lastVal = encodedFile;
    return lastVal;
}