出内存文件编码为Base64时 [英] Out of memory when encoding file to base64

查看:182
本文介绍了出内存文件编码为Base64时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自Apache公地使用Base64

Using Base64 from Apache commons

public byte[] encode(File file) throws FileNotFoundException, IOException {
        byte[] encoded;
        try (FileInputStream fin = new FileInputStream(file)) {
            byte fileContent[] = new byte[(int) file.length()];
            fin.read(fileContent);
            encoded = Base64.encodeBase64(fileContent);
        }
        return encoded;   
}


Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
    at org.apache.commons.codec.binary.BaseNCodec.encode(BaseNCodec.java:342)
    at org.apache.commons.codec.binary.Base64.encodeBase64(Base64.java:657)
    at org.apache.commons.codec.binary.Base64.encodeBase64(Base64.java:622)
    at org.apache.commons.codec.binary.Base64.encodeBase64(Base64.java:604)

我在做小的应用程序的移动设备。

I'm making small app for mobile device.

推荐答案

您不能将整个文件只加载到内存中,喜欢这里:

You cannot just load the whole file into memory, like here:

byte fileContent[] = new byte[(int) file.length()];
fin.read(fileContent);

相反,通过加载块和连接$ C $文件块c将其零件。 Base64是一个简单的编码,就足以在一段时间(编码后,这将产生4个字节)来加载3个字节和连接code他们。出于性能方面的考虑3个字节装载的倍数,例如3000字节 - 应该就好了。还要考虑缓冲输入文件。

Instead load the file chunk by chunk and encode it in parts. Base64 is a simple encoding, it is enough to load 3 bytes and encode them at a time (this will produce 4 bytes after encoding). For performance reasons consider loading multiples of 3 bytes, e.g. 3000 bytes - should be just fine. Also consider buffering input file.

一个例子:

byte fileContent[] = new byte[3000];
try (FileInputStream fin = new FileInputStream(file)) {
    while(fin.read(fileContent) >= 0) {
         Base64.encodeBase64(fileContent);
    }
}

请注意,你不能简单地追加 Base64.en $结果C $ cBase64()连接codeD bbyte阵列。其实,这是不加载的文件,但它编码为Base64导致内存外的问题。这是理解的,因为Base64编码的版本是更大的(并且已经有占大量内存的文件)。

Note that you cannot simply append results of Base64.encodeBase64() to encoded bbyte array. Actually, it is not loading the file but encoding it to Base64 causing the out-of-memory problem. This is understandable because Base64 version is bigger (and you already have a file occupying a lot of memory).

考虑更改方法:

public void encode(File file, OutputStream base64OutputStream)

和直接发送的Base64恩codeD数据传输到 base64OutputStream 而不是返回了。

and sending Base64-encoded data directly to the base64OutputStream rather than returning it.

更新:感谢的 @StephenC 的我开发容易得多版本:

UPDATE: Thanks to @StephenC I developed much easier version:

public void encode(File file, OutputStream base64OutputStream) {
  InputStream is = new FileInputStream(file);
  OutputStream out = new Base64OutputStream(base64OutputStream)
  IOUtils.copy(is, out);
  is.close();
  out.close();
}

它使用<一个href=\"http://commons.apache.org/$c$cc/api-release/org/apache/commons/$c$cc/binary/Base64OutputStream.html\"><$c$c>Base64OutputStream该输入转换为Base64的上即时和<一个href=\"http://commons.apache.org/io/apidocs/org/apache/commons/io/IOUtils.html\"><$c$c>IOUtils类从 Apache的百科全书IO

注意:您必须关闭的FileInputStream Base64OutputStream 明确打印 = 如果需要的话,但缓冲由 IOUtils.copy()。

Note: you must close the FileInputStream and Base64OutputStream explicitly to print = if required but buffering is handled by IOUtils.copy().

这篇关于出内存文件编码为Base64时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆