191

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?!

Mat
  • 202,337
  • 40
  • 393
  • 406
0909EM
  • 4,761
  • 3
  • 29
  • 40
  • Note that normally you would use a base 64 encoding (`0QEQVAJlblNvbWUgTkZDIERhdGE=`) or hexadecimal encoding (`d101105402656e536f6d65204e46432044617461`) of the bytes; not an array encoding with separators, warts and whatnot. So this Q/A is - or should not be - applicable for 99% of situations. And note that TCP and HTTP are fully capable of handling binary for larger amounts of data using `POST`. – Maarten Bodewes Dec 27 '21 at 12:05

12 Answers12

282

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.parseByte(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.

Boann
  • 48,794
  • 16
  • 117
  • 146
Yanick Rochon
  • 51,409
  • 25
  • 133
  • 214
  • 2
    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
  • 1
    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 04 '13 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 04 '13 at 17:06
  • 4
    To add to what is otherwise a correct (albeit incomplete) answer: 1) Any byte[] array being converted into a String in Java should specify the character-set. Is the byte[] array UTF-8 or something else? Not being specific or knowing what it is can create bugs. 2) Java uses Big-Endian encoding but M$ systems for example use Little-Endian. When dealing with byte[] arrays that are Strings (character based), it is no problem. However, if the byte[] array represents a number, the 'endianess' of the source/target systems matters. – Darrell Teague Mar 13 '14 at 16:26
138
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

That outputs "cool string" to the console.

It's pretty darn easy.

CorayThan
  • 17,174
  • 28
  • 113
  • 161
  • 6
    So many downvotes, but so few explanations ... Does what I said not work? It worked when I used it, and the question is how to convert from bytes to strings and back again, right? – CorayThan Mar 08 '13 at 18:13
  • 2
    The answer that solved this is actually marked as the answer. From memory it isn't as simple as you've suggested... See Yanick's answer, I think you've misunderstood what I was asking, but thanks for the input. – 0909EM Mar 26 '13 at 15:27
  • @0909EM There are of course many solutions to the question you posted. I was just posting a different answer which is more simple, and which I think solves the issue just as well. – CorayThan Mar 26 '13 at 15:38
  • 10
    @CorayThan Actually no, this doesn't address the OP's question at all. If you actually read thru it, you'll see that the `byte[]` he is receiving is represented as a `String`; i.e. `"[97, 98, 99]"` not `[97, 98, 99]`. Meaning, your answer doesn't even apply to this situation. – arkon Jun 05 '13 at 16:30
  • 2
    Your answer is `String` to `byte[]` to `String`. I think the question requirement is `byte[]` to `String` to `byte[]`. – Wundwin Born May 09 '14 at 16:22
  • 1
    @suninsky It's easier to show a nice example with `String` to `byte[]` to `String`, and either way it gives all the information you need. – CorayThan May 09 '14 at 17:18
  • 2
    I came to this thread based on question subject, and this answer answers that completely. The fact that OP had a different situation in the question body is a different discussion. – eis Dec 27 '14 at 21:07
  • 15
    May even be the wrong response for the asked question, but it helped me to solve a problem. That´s why people should think a little more before downgrading someone else´s reply. Thank you CorayThan! – Roberto Santos Mar 01 '15 at 04:20
  • 1
    @CorayThan : The objective of the question is to answer about Byte array to String and then back to Byte Array. Although your answer is correct but it should be answered vice versa. – Murtaza Kanchwala Feb 13 '17 at 09:30
22

What I did:

return to clients:

byte[] result = ****encrypted data****;

String str = Base64.encodeBase64String(result);

return str;

receive from clients:

 byte[] bytes = Base64.decodeBase64(str);

your data will be transferred in this format:

OpfyN9paAouZ2Pw+gDgGsDWzjIphmaZbUyFx5oRIN1kkQ1tDbgoi84dRfklf1OZVdpAV7TonlTDHBOr93EXIEBoY1vuQnKXaG+CJyIfrCWbEENJ0gOVBr9W3OlFcGsZW5Cf9uirSmx/JLLxTrejZzbgq3lpToYc3vkyPy5Y/oFWYljy/3OcC/S458uZFOc/FfDqWGtT9pTUdxLDOwQ6EMe0oJBlMXm8J2tGnRja4F/aVHfQddha2nUMi6zlvAm8i9KnsWmQG//ok25EHDbrFBP2Ia/6Bx/SGS4skk/0couKwcPVXtTq8qpNh/aYK1mclg7TBKHfF+DHppwd30VULpA== 
Saorikido
  • 2,173
  • 2
  • 26
  • 37
7

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.

bluish
  • 26,356
  • 27
  • 122
  • 180
Kal
  • 24,724
  • 7
  • 65
  • 65
6

Its simple to convert byte array to string and string back to byte array in java. we need to know when to use 'new' in the right way. It can be done as follows:

byte array to string conversion:

byte[] bytes = initializeByteArray();
String str = new String(bytes);

String to byte array conversion:

String str = "Hello"
byte[] bytes = str.getBytes();

For more details, look at: http://evverythingatonce.blogspot.in/2014/01/tech-talkbyte-array-and-string.html

Ulrich Thomas Gabor
  • 6,584
  • 4
  • 27
  • 41
user3469161
  • 77
  • 1
  • 1
  • 2
    No, you've not read the question or perhaps you've not understood the problem. As you'll note the question was answered years ago... – 0909EM Apr 01 '14 at 23:51
3

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.

Littm
  • 4,923
  • 4
  • 30
  • 38
fuzzyBSc
  • 823
  • 8
  • 7
2

[JDK8]

import java.util.Base64;

To string:

String str = Base64.getEncoder().encode(new byte[]{ -47, 1, 16, ... });

To byte array:

byte[] bytes = Base64.getDecoder().decode("JVBERi0xLjQKMyAwIG9iago8P...");
2

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().

JAB
  • 20,783
  • 6
  • 71
  • 80
  • 1
    `[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 09: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 05 '12 at 16:34
1

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.

bluish
  • 26,356
  • 27
  • 122
  • 180
Martin
  • 138
  • 2
0

Use the below code API to convert bytecode as string to Byte array.

 byte[] byteArray = DatatypeConverter.parseBase64Binary("JVBERi0xLjQKMyAwIG9iago8P...");
Ajay Kumar
  • 4,864
  • 1
  • 41
  • 44
-1

[JAVA 8]

import java.util.Base64;

String dummy= "dummy string";
byte[] byteArray = dummy.getBytes();

byte[] salt = new byte[]{ -47, 1, 16, ... }
String encoded = Base64.getEncoder().encodeToString(salt);
3logy
  • 2,634
  • 8
  • 46
  • 99
-1

You can do the following to convert byte array to string and then convert that string to byte array:

// 1. convert byte array to string and then string to byte array

    // convert byte array to string
    byte[] by_original = {0, 1, -2, 3, -4, -5, 6};
    String str1 = Arrays.toString(by_original);
    System.out.println(str1); // output: [0, 1, -2, 3, -4, -5, 6]

    // convert string to byte array
    String newString = str1.substring(1, str1.length()-1);
    String[] stringArray = newString.split(", ");
    byte[] by_new = new byte[stringArray.length];
    for(int i=0; i<stringArray.length; i++) {
        by_new[i] = (byte) Integer.parseInt(stringArray[i]);
    }
    System.out.println(Arrays.toString(by_new)); // output: [0, 1, -2, 3, -4, -5, 6]

But to convert the string to byte array and then convert that byte array to string, below approach can be used:

// 2. convert string to byte array and then byte array to string

    // convert string to byte array
    String str2 = "[0, 1, -2, 3, -4, -5, 6]";
    byte[] byteStr2 = str2.getBytes(StandardCharsets.UTF_8);
    // Now byteStr2 is [91, 48, 44, 32, 49, 44, 32, 45, 50, 44, 32, 51, 44, 32, 45, 52, 44, 32, 45, 53, 44, 32, 54, 93]

    // convert byte array to string
    System.out.println(new String(byteStr2, StandardCharsets.UTF_8)); // output: [0, 1, -2, 3, -4, -5, 6]

I have also answered the same in the following question: https://stackoverflow.com/a/70486387/17364272