java - IllegalArgumentException using Java8 Base64 decoder -
i wanted use base64.java encode , decode files. encode.wrap(inputstream)
, decode.wrap(inputstream)
worked runned slowly. used following code.
public static void decodefile(string inputfilename, string outputfilename) throws filenotfoundexception, ioexception { base64.decoder decoder = base64.getdecoder(); inputstream in = new fileinputstream(inputfilename); outputstream out = new fileoutputstream(outputfilename); byte[] inbuff = new byte[buff_size]; //final int buff_size = 1024; byte[] outbuff = null; while (in.read(inbuff) > 0) { outbuff = decoder.decode(inbuff); out.write(outbuff); } out.flush(); out.close(); in.close(); }
however, throws
exception in thread "awt-eventqueue-0" java.lang.illegalargumentexception: input byte array has wrong 4-byte ending unit @ java.util.base64$decoder.decode0(base64.java:704) @ java.util.base64$decoder.decode(base64.java:526) @ base64coder.javabase64filecoder.decodefile(javabase64filecoder.java:69) ...
after changed final int buff_size = 1024;
final int buff_size = 3*1024;
, code worked. since "buff_size" used encode file, believe there wrong file encoded (1024 % 3 = 1, means paddings added in middle of file).
also, @jon skeet , @tagir valeev mentioned, should not ignore return value inputstream.read()
. so, modified code below.
(however, have mention code run faster using wrap()
. noticed speed difference because had coded , intensively used base64.encodefile()/decodefile() long before jdk8 released. now, buffed jdk8 code runs fast original code. so, not know going on wrap()
... )
public static void decodefile(string inputfilename, string outputfilename) throws filenotfoundexception, ioexception { base64.decoder decoder = base64.getdecoder(); inputstream in = new fileinputstream(inputfilename); outputstream out = new fileoutputstream(outputfilename); byte[] inbuff = new byte[buff_size]; byte[] outbuff = null; int bytesread = 0; while (true) { bytesread = in.read(inbuff); if (bytesread == buff_size) { outbuff = decoder.decode(inbuff); } else if (bytesread > 0) { byte[] tempbuff = new byte[bytesread]; system.arraycopy(inbuff, 0, tempbuff, 0, bytesread); outbuff = decoder.decode(tempbuff); } else { out.flush(); out.close(); in.close(); return; } out.write(outbuff); } }
special @jon skeet , @tagir valeev.
i suspect problem you're ignoring return value inputstream.read
, other check end of stream. this:
while (in.read(inbuff) > 0) { // decodes *complete* buffer outbuff = decoder.decode(inbuff); out.write(outbuff); }
should be
int bytesread; while ((bytesread = in.read(inbuff)) > 0) { outbuff = decoder.decode(inbuff, 0, bytesread); out.write(outbuff); }
i wouldn't expect faster using wrap
though.
Comments
Post a Comment