OutOfMemory when creating Base64 string in java?

社会主义新天地 提交于 2019-12-31 04:38:12

问题


I used ostermillerutils library to create base64 string but I get OutOfMemory error if the image is heavy. If the image I try to convert is a simple image, the code is working fine.

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;
}

I also tried doing this but the base64 was incorrect when I tried to decode it.

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();
        }
    }

}

Please suggest solutions for JDK 1.4 and also for later versions of Java.


回答1:


If you like to write the encoded content straight into a file then use the following code

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();
}

IOUtils class from Apache Commons IO.

EDIT Since you want to do it using BufferedWriter, use it as follows

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



回答2:


It sounds like the problem is that you're having to manipulate too much data in memory when you read the entire image. One fix would be to increase the Java heap size until you have enough memory, but that would just be avoiding the problem rather than solving it.

A better option would be to look at a streaming implementation of a Base64 encoder. This would mean you're only working on a subset of the image at any time. I believe that Base64OutputStream from Apache Commons would do the job for you.




回答3:


I've fixed my problem by using javabase64-1.3.1.jar library.

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

I stored the base64 string to a text file first.

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;
}

then send each line to smtp's socket outputstream.




回答4:


From Java 8 onwards, there is a simple way to implement base64 encoding in an output stream with one line of code and no external dependencies:

   import java.util.Base64;

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

Base64 also provides other flavors of base64 encoder; see javadocs:

  • Base64
  • Base64.Encoder.wrap


来源:https://stackoverflow.com/questions/22163825/outofmemory-when-creating-base64-string-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!