Base64 encoding & decoding

harishalwala
harishalwala used Ask the Experts™
on
I am working with Base64 encoding & Decoding of all types of files, I get the stream from socket. I tried using Base64 encoder & Base64Decoder class from Java2s website. It works fine encoding & decoding for the txt file & png files. But when I try with doc/xls/pdf it fails, it says file corrupted, after decoding.

I tried even with Apache common codec jar Base64. I didnot understand how to use with InputStreams, I see it works for String.

Any help please.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Awarded 2011
Awarded 2011
Commented:
I think you should read the contents of the file into byte array and then encode and decode byte array - then you shoiulkd be able to work with binary files, not just text files
Commented:
Try using..

http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64InputStream.html

You need to create an input stream and pass it to Base64InputStream constructor (with two arguments), then use its read methods to get the encoded/decoded stream.

Awarded 2011
Awarded 2011

Commented:

This code reads Excel file encodes it into string then
decodes the string and writes it back to another file -
which I opened with Excel and found it the same:


import sun.misc.BASE64Encoder;

import java.io.*;

public class EncodeDecodeBinary {

    public static void main(String[] args) {
        try{
            BufferedInputStream ba = new BufferedInputStream(new FileInputStream("test1.xls"));
            int av = ba.available();
              byte[] buffer = new byte[av];
            int n = ba.read(buffer, 0, av);
            ba.close();
            ByteArrayInputStream bas = new ByteArrayInputStream(buffer);


            String encode = new sun.misc.BASE64Encoder().encode(buffer);

           System.out.println(encode);

            byte [] buffer1 = new sun.misc.BASE64Decoder().decodeBuffer(encode);

                  BufferedOutputStream baout = new BufferedOutputStream(new FileOutputStream("test2.xls"));
                  baout.write(buffer1,0,buffer1.length);
                  baout.close();






        }   catch(Exception ex){
            ex.printStackTrace();
        }

    }

}

Open in new window



Encoded String printouut (truncated):
0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAA
EAAAHAAAAAEAAAD+////AAAAAAAAAAD/////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////9
////HwAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8A
AAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAAABgAAAAZAAAAGgAAABsAAAD+/////v//
/x4AAAD+/////v//////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////1IA

Open in new window

Become a Microsoft Certified Solutions Expert

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

Awarded 2011
Awarded 2011

Commented:
I tested the above code for several types of files - .xls, .jpg, .txt  - and it worked fine for all of them

Commented:
It is not a good practice to use classes from sun.misc. Because they are not documented, and they can be changed/removed at any time.

Also, reading the whole file in memory to pass to coder/decoder is not a good idea, as there can be a possibility of out of memory exceptions.
Top Expert 2016

Commented:
Right on both counts!
Awarded 2011
Awarded 2011

Commented:

The code below will allow you to read as big files as you want, though it is not often that you'll probably
be reading files which will casue you out of memory exceptions on the previous version.
(make sure to increase BUFFER_SIZE to something reasonable - I made it very small for experiments).



My IDE imedniately recognized BASE64Encoder in Java 6
For BASE64InputStream you need to carry additional jar.

I';m doing Java for almost as many years as Java exists and don't recall a single case where
I needed to remove some older class from my old program  because it stopped being actually supported.





import sun.misc.BASE64Encoder;

import java.io.*;

public class EncodeDecodeBinary {

    public static void main(String[] args) {
        try{
            BufferedInputStream ba = new BufferedInputStream(new FileInputStream("test1.xls"));
             BufferedOutputStream baout = new BufferedOutputStream(new FileOutputStream("test4.xls"));
            int BUFFER_SIZE=100;
             byte[] buffer = new byte[BUFFER_SIZE];
            while(true){
            int av = ba.available();
                if(av == 0)break;
                int readB = Math.min(av, BUFFER_SIZE);


            int n = ba.read(buffer, 0, readB);


                byte [] buffer2 = new byte[readB];
                for(int j=0; j<readB; j++)buffer2[j]=buffer[j];

            String encode = new sun.misc.BASE64Encoder().encode(buffer2);


           System.out.println(encode);

            byte [] buffer1 = new sun.misc.BASE64Decoder().decodeBuffer(encode);


                  baout.write(buffer1,0,buffer1.length);

            }
            ba.close();
            baout.close();










        }   catch(Exception ex){
            ex.printStackTrace();
        }





    }

}

Open in new window

Commented:
Check this..

"I tried even with Apache common codec jar Base64. I didnot understand how to use with InputStreams"
Top Expert 2016
Commented:
>>I tried even with Apache common codec jar Base64. I didnot understand how to use with InputStreams

harishalwala, unlike the sun.misc packages, the commons codec classes are fully documented. All you need to do is wrap the socket input stream in a Base64InputStream:

http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64InputStream.html#Base64InputStream(java.io.InputStream, boolean)

What difficulty did you have?

Author

Commented:
closed
Top Expert 2016

Commented:
:)

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial