Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you convert binary data to Strings and back in Java?

I have binary data in a file that I can read into a byte array and process with no problem. Now I need to send parts of the data over a network connection as elements in an XML document. My problem is that when I convert the data from an array of bytes to a String and back to an array of bytes, the data is getting corrupted. I've tested this on one machine to isolate the problem to the String conversion, so I now know that it isn't getting corrupted by the XML parser or the network transport.

What I've got right now is

byte[] buffer = ...; // read from file // a few lines that prove I can process the data successfully String element = new String(buffer); byte[] newBuffer = element.getBytes(); // a few lines that try to process newBuffer and fail because it is not the same data anymore 

Does anyone know how to convert binary to String and back without data loss?

Answered: Thanks Sam. I feel like an idiot. I had this answered yesterday because my SAX parser was complaining. For some reason when I ran into this seemingly separate issue, it didn't occur to me that it was a new symptom of the same problem.

EDIT: Just for the sake of completeness, I used the Base64 class from the Apache Commons Codec package to solve this problem.

like image 703
Bill the Lizard Avatar asked Aug 21 '08 18:08

Bill the Lizard


People also ask

How do you convert binary to string?

The naive approach is to convert the given binary data in decimal by taking the sum of binary digits (dn) times their power of 2*(2^n). The binary data is divided into sets of 7 bits because this set of binary as input, returns the corresponding decimal value which is ASCII code of the character of a string.

Can we convert byte to string in Java?

Given a Byte value in Java, the task is to convert this byte value to string type. One method is to create a string variable and then append the byte value to the string variable with the help of + operator. This will directly convert the byte value to a string and add it in the string variable.

What are converting numbers to and from strings in Java?

The toString() method Or, use the normal version of the Integer class' object. This cannot be used with the primitive type int, so remember to convert it to an Integer first by passing it to the constructor or simple assignment using '=' operator (see the example below) : Integer i = 123; i.


2 Answers

String(byte[]) treats the data as the default character encoding. So, how bytes get converted from 8-bit values to 16-bit Java Unicode chars will vary not only between operating systems, but can even vary between different users using different codepages on the same machine! This constructor is only good for decoding one of your own text files. Do not try to convert arbitrary bytes to chars in Java!

Encoding as base64 is a good solution. This is how files are sent over SMTP (e-mail). The (free) Apache Commons Codec project will do the job.

byte[] bytes = loadFile(file);           //all chars in encoded are guaranteed to be 7-bit ASCII byte[] encoded = Base64.encodeBase64(bytes); String printMe = new String(encoded, "US-ASCII"); System.out.println(printMe); byte[] decoded = Base64.decodeBase64(encoded); 

Alternatively, you can use the Java 6 DatatypeConverter:

import java.io.*; import java.nio.channels.*; import javax.xml.bind.DatatypeConverter;  public class EncodeDecode {       public static void main(String[] args) throws Exception {     File file = new File("/bin/ls");     byte[] bytes = loadFile(file, new ByteArrayOutputStream()).toByteArray();     String encoded = DatatypeConverter.printBase64Binary(bytes);     System.out.println(encoded);     byte[] decoded = DatatypeConverter.parseBase64Binary(encoded);     // check     for (int i = 0; i < bytes.length; i++) {       assert bytes[i] == decoded[i];     }   }    private static <T extends OutputStream> T loadFile(File file, T out)                                                        throws IOException {     FileChannel in = new FileInputStream(file).getChannel();     try {       assert in.size() == in.transferTo(0, in.size(), Channels.newChannel(out));       return out;     } finally {       in.close();     }   } } 
like image 194
McDowell Avatar answered Oct 04 '22 11:10

McDowell


If you encode it in base64, this will turn any data into ascii safe text, but base64 encoded data is larger than the orignal data

like image 28
Sam Avatar answered Oct 04 '22 09:10

Sam