I'm trying to understand a byte[] to string, string representation of byte[] to byte[] conversion... I convert my byte[] to a string to send, I then expect my web service (written in python) to echo the data straight back to the client.

When I send the data from my Java application...

Arrays.toString(data.toByteArray())

Bytes to send..

[B@405217f8

Send (This is the result of Arrays.toString() which should be a string representation of my byte data, this data will be sent across the wire):

[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]

On the python side, the python server returns a string to the caller (which I can see is the same as the string I sent to the server

[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]

The server should return this data to the client, where it can be verified.

The response my client receives (as a string) looks like

[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]

I can't seem to figure out how to get the received string back into a byte[]

Whatever I seem to try I end up getting a byte array which looks as follows...

[91, 45, 52, 55, 44, 32, 49, 44, 32, 49, 54, 44, 32, 56, 52, 44, 32, 50, 44, 32, 49, 48, 49, 44, 32, 49, 49, 48, 44, 32, 56, 51, 44, 32, 49, 49, 49, 44, 32, 49, 48, 57, 44, 32, 49, 48, 49, 44, 32, 51, 50, 44, 32, 55, 56, 44, 32, 55, 48, 44, 32, 54, 55, 44, 32, 51, 50, 44, 32, 54, 56, 44, 32, 57, 55, 44, 32, 49, 49, 54, 44, 32, 57, 55, 93]

or I can get a byte representation which is as follows:

B@2a80d889

Both of these are different from my sent data... I'm sure Im missing something truly simple....

Any help?!

share|improve this question
feedback

5 Answers

up vote 15 down vote accepted

You can't just take the returned string and construct a string from it... it's not a byte[] data type anymore, it's already a string; you need to parse it. For example :

String response = "[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]";      // response from the Python script

String[] byteValues = response.substring(1, response.length() - 1).split(",");
byte[] bytes = new byte[byteValues.length];

for (int i=0, len=bytes.length; i<len; i++) {
   bytes[i] = Byte.valueof(byteValues[i].trim());     
}

String str = new String(bytes);

** EDIT **

You get an hint of your problem in your question, where you say "Whatever I seem to try I end up getting a byte array which looks as follows... [91, 45, ...", because 91 is the byte value for [, so [91, 45, ... is the byte array of the string "[-45, 1, 16, ..." string.

The method Arrays.toString() will return a String representation of the specified array; meaning that the returned value will not be a array anymore. For example :

byte[] b1 = new byte[] {97, 98, 99};

String s1 = Arrays.toString(b1);
String s2 = new String(b1);

System.out.println(s1);        // -> "[97, 98, 99]"
System.out.println(s2);        // -> "abc";

As you can see, s1 holds the string representation of the array b1, while s2 holds the string representation of the bytes contained in b1.

Now, in your problem, your server returns a string similar to s1, therefore to get the array representation back, you need the opposite constructor method. If s2.getBytes() is the opposite of new String(b1), you need to find the opposite of Arrays.toString(b1), thus the code I pasted in the first snippet of this answer.

share|improve this answer
Awesome! I think you've completely understood what I was after... I'm not from a Java background, so I couldn't really figure out the conversion I needed. Just for info, I'm sending s1 to the server, and the server is replying with s1 (I can verify that the server received and replied with the data in s1), so I did need the opposite of Arrays.toString() as you suggested... AND your solution is pretty darn good! Cheers! – 0909EM Jul 13 '11 at 21:39
Thank you Yanick. But it loops for 2046 times for each image as the value of bytes.length is 2046. Is there any other method to do this? – Gugan Feb 4 at 12:19
If the data you are receiving is really a human readable string that needs to be parsed like the value of the variable response in my answer, then unfortunately no, there is no other way. The best way would be for you to receive the bytes as raw data (as binary) instead of a string, or perhaps even as a Base64 string, which would only require you to convert it back as a base 256 (binary) value. – Yanick Rochon Feb 4 at 17:06
feedback

What Arrays.toString() does is create a string representation of each individual byte in your byteArray.

Please check the API documentation Arrays API

To convert your response string back to the original byte array, you have to use split(",") or something and convert it into a collection and then convert each individual item in there to a byte to recreate your byte array.

share|improve this answer
feedback

Can you not just send the bytes as bytes, or convert each byte to a character and send as a string? Doing it like you are will take up a minimum of 85 characters in the string, when you only have 11 bytes to send. You could create a string representation of the bytes, so it'd be "[B@405217f8", which can easily be converted to a bytes or bytearray object in Python. Failing that, you could represent them as a series of hexadecimal digits ("5b42403430353231376638") taking up 22 characters, which could be easily decoded on the Python side using binascii.unhexlify().

share|improve this answer
[B@405217f8 is the Java object ID of the array, not the array's content. Object ID certainly cannot "easily be converted to a bytes or bytearray object in python". The best you can do size-wise is to convert the byte[] to a base64 string. – Boris B. Nov 23 '12 at 9:57
You are correct, I naively assumed 0909EM knew enough to differentiate between the (typed) address of an object and the object's contents. – JAB Dec 5 '12 at 16:34
feedback

If you want to convert the string back into a byte array you will need to use String.getBytes() (or equivalent Python function) and this will allow you print out the original byte array.

share|improve this answer
feedback

The kind of output you are seeing from your byte array ([B@405217f8) is also an output for a zero length byte array (ie new byte[0]). It looks like this string is a reference to the array rather than a description of the contents of the array like we might expect from a regular collection's toString() method.

As with other respondents, I would point you to the String constructors that accept a byte[] parameter to construct a string from the contents of a byte array. You should be able to read raw bytes from a socket's InputStream if you want to obtain bytes from a TCP connection.

If you have already read those bytes as a String (using an InputStreamReader), then, the string can be converted to bytes using the getBytes() function. Be sure to pass in your desired character set to both the String constructor and getBytes() functions, and this will only work if the byte data can be converted to characters by the InputStreamReader.

If you want to deal with raw bytes you should really avoid using this stream reader layer.

share|improve this answer
feedback

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.