-1

In a servlet I had to read an image file from disk, encode it to Base64 and then send back to the client. Because I only found samples for iOS, Python and some other kinds (principally all do it the same way) I thought I post my code here to help others ;)

CAUTION! This should only work for files up to 2GB: setting capacity of ByteBuffer only takes an int.

0

2 Answers 2

1

Why so complicated and why read the complete image into memory? A much simpler solution:

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder(); enc.encode(new FileInputStream("/path/to/file.whatever"), response.getOutputStream()); } 
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the hint, but the code I posted is only a part of the whole action I do serverside. I have to pack the data among other in a greater response. But I will see if I could make a chain for writing directly on OutputStream. But +1 anyway
A fat downvote for the reason mentioned in oracle.com/technetwork/java/faq-sun-packages-142232.html
1
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { FileInputStream in = null; try { File file = new File(getServletContext().getRealPath("/<thePath>/<fileName>")); ByteBuffer buff = ByteBuffer.wrap(new byte[(int)image.length() + (image.length() % 1024 > 0 ? 1024 : 0)]); byte[] b = new byte[1024]; in = new FileInputStream(file); while(in.read(b) != -1) { buff.put(b); } response.getWriter().write(Base64.encode(buff.array())); } catch(Exception e) { String msg = "Fehler beim lesen des Bildes"; LOG.log(Level.SEVERE, msg, e); response.sendError(500, msg); return; } finally { if(in != null) in.close(); } } 

CAUTION! This should only work for files up to 2GB: setting capacity of ByteBuffer only takes an int.

6 Comments

use org.apache.commons.codec.binary.Base64InputStream
Hey that's a nice package I just didn't know (yeah, shame on me). Thanks for the advice. But in the end I have to get A String (code is just a snippet) and pack it with some other data before sending the response, so I don't see actually an additional value for me, just that I got an additional lib. But I think I will use it future projects.
basic idea: don't use byte[] or String to store large amount of data. Java has stream implementations for almost all cases.
So far so good. It seems I'm too stupid: I don't see how to do it with Base64InputStream in another way like I did. And if its just about not loading data in memory I find Udo Klimaschewskis answer cleaner and it don't need an additional library.
don't use sun.misc.* classes, it is internal java API and can be changed in future. oracle.com/technetwork/java/faq-sun-packages-142232.html. And you can use Base64InputStream like this: Base64InputStream stream = new Base64InputStream(new FileInputStream("path to file")); IOUtils.copy(stream, response.getOutputStream());`
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.