在java中创建Base64字符串时OutOfMemory?

时间:2014-03-04 05:39:01

标签: java base64 out-of-memory

我使用ostermillerutils库来创建base64字符串,但如果图像很重,我会收到OutOfMemory错误。如果我尝试转换的图像是一个简单的图像,代码工作正常。

public String createBase64String(InputStream in) {
    //collect = new ByteArrayOutputStream();
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] buf = new byte[1024];
    try {
        for(int readNum; (readNum = in.read(buf)) != -1; ) {
            bos.write(buf, 0, readNum);
        }
    }
    catch (IOException ex) {
        Logger.getInstance().debug("XML createBase64String: IOException");
        return null;
    }
    finally {
        if (in != null) {
            try {
                in.close();

            }
            catch (IOException ex) {
                ;
            }
        }
    }
    byte[] ba = bos.toByteArray();
    String coded = Base64.encodeToString(ba);
    return coded;
}

附加信息:代码应符合JDK 1.4。

public void createBase64String(InputStream in) throws IOException {
    //collect = new ByteArrayOutputStream();

    byte[] buf = new byte[1024];
    int readNum = 0;

    try {
        while((readNum = in.read(buf)) != -1)  
         {    
            smtp.addBase64(Base64.encodeBase64String(buf));
         }  
    }
    catch (IOException ex) {
        Logger.getInstance().debug("XML createBase64String: IOException");
    }
    finally {
        if (in != null) {
            in.close();
        }
    }

}

我试过这样做但是当我尝试解码时,base64不正确。

4 个答案:

答案 0 :(得分:2)

如果您想将编码内容直接写入文件,请使用以下代码

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();
}
来自Apache Commons IO的

IOUtils类。

修改 由于您希望使用BufferedWriter执行此操作,请按以下方式使用

 OutputStream out = Base64OutputStream(smtpSocket.getOutputStream()); 
 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
 IOUtils.copy(is, bw);

答案 1 :(得分:1)

听起来问题是,当您阅读整个图像时,您必须在内存中操作太多数据。一个解决方法是增加Java堆大小,直到你有足够的内存,但这只是避免问题而不是解决它。

更好的选择是查看Base64编码器的流式实现。这意味着您只能在任何时候处理图像的子集。我相信来自Apache Commons的Base64OutputStream将为您完成这项工作。

答案 2 :(得分:0)

我已经使用javabase64-1.3.1.jar库解决了我的问题。

OutputStream fos2 = FileUtil.getOutputStream(base64FileName, FileUtil.HDD);
InputStream  in2 = FileUtil.getInputStream(fileName, FileUtil.HDD);
Base64.encode(in2, fos2);
in2.close();
fos2.close();

我首先将base64字符串存储到文本文件中。

public void createBase64String(InputStream in) throws IOException {
    baos = new ByteArrayOutputStream();
    byte[] buf = new byte[BUFFER_SIZE];
    int readNum = 0;
    smtp.addBase64("\t\t");

    try {
        while ((readNum = in.read(buf)) >= 0) {
            baos.write(buf, 0, readNum);
            smtp.addBase64(baos.toString());
            baos.reset();
        }
    }
    catch (IOException ex) {
        LogUtil.error("Sending of Base64 String to SMTP: IOException: " + ex);
    }
    finally {
        if (in != null) {
            in.close();
            baos.close();
        }
    }

    baos = null;
    buf = null;
}

然后将每一行发送到smtp的套接字输出流。

答案 3 :(得分:0)

从Java 8开始,有一种简单的方法可以在输出流中实现base64编码,只需一行代码,并且没有外部依赖项:

   import java.util.Base64;

   OutputStream os = ...
   OutputStream base64 = Base64.getEncoder().wrap(os);

Base64还提供了其他形式的base64编码器;参见javadocs: