Java字节数组到字符串到字节数组


180

我试图理解一个byte []到字符串,一个byte []的字符串表示形式到byte []转换...我将我的byte []转换成一个要发送的字符串,然后我希望我的Web服务(用python编写)将数据直接回显给客户端。

当我从Java应用程序发送数据时...

Arrays.toString(data.toByteArray())

字节发送..

[B@405217f8

发送(这是Arrays.toString()的结果,它应该是我的字节数据的字符串表示形式,该数据将通过电线发送):

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

在python端,python服务器将字符串返回给调用方(我可以看到的与我发送给服务器的字符串相同

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

服务器应将此数据返回给客户端,在此可以对其进行验证。

我的客户收到的响应(以字符串形式)看起来像

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

我似乎无法弄清楚如何将接收到的字符串变回字节[]

无论我尝试什么,我最终都会得到一个字节数组,其外观如下:

[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]

或者我可以得到如下的字节表示形式:

B@2a80d889

两者都与我发送的数据不同...我确定我缺少真正简单的内容...。

有帮助吗?

Answers:


272

您不能只使用返回的字符串并从中构造一个字符串……它不再是byte[]数据类型,它已经是一个字符串;您需要解析它。例如 :

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);

** 编辑 **

您会在问题中得到提示,您说“ Whatever I seem to try I end up getting a byte array which looks as follows... [91, 45, ...”,因为91是的字节值[,所以[91, 45, ...字符串“ [-45, 1, 16, ...” 的字节数组也是如此。

该方法Arrays.toString()将返回String指定数组的表示形式。表示返回的值将不再是数组。例如 :

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";

如您所见,s1保存数组 的字符串表示形式b1,而s2保存包含在其中的字节的字符串表示形式b1

现在,在您的问题中,您的服务器返回了一个类似于的字符串s1,因此要获取数组表示,您需要相反的构造方法。如果s2.getBytes()是的反面new String(b1),则需要找到的反面Arrays.toString(b1),因此我将其粘贴在此答案的第一段代码中。


太棒了!我认为您已经完全了解我所追求的...我不是来自Java背景,所以我无法真正弄清楚我需要的转换。只是为了提供信息,我将s1发送到服务器,并且服务器正在用s1答复(我可以验证服务器是否已接收并回复了s1中的数据),所以我确实需要Arrays.toString()的相反内容您建议...而且您的解决方案非常不错!干杯!
0909EM 2011年

谢谢亚尼克。但是它为每个图像循环2046次,因为bytes.length的值为2046。还有其他方法可以这样做吗?
古根

如果您要接收的数据确实是人类可读的字符串,需要像response我的答案中的变量值一样进行解析,那么很遗憾,没有其他方法。最好的方法是让您将字节作为原始数据(作为二进制)而不是字符串或什至作为Base64字符串来接收,这仅需要您将其转换回为基数256(二进制)值。
Yanick Rochon

3
要添加正确的答案(尽管不完整),请执行以下操作:1)在Java中将任何byte []数组转换为String都应指定字符集。是byte []数组UTF-8还是其他?不够具体或不知道它是什么会造成错误。2)Java使用Big-Endian编码,但是M $系统使用Little-Endian。处理字符串(基于字符)的byte []数组时,这没有问题。但是,如果byte []数组表示一个数字,则源/目标系统的'endianess'很重要。
Darrell Teague 2014年

130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

它将“酷字符串”输出到控制台。

真是太容易了。


6
这么多否决票,却没有那么多解释...我说的不行吗?当我使用它时它起作用了,问题是如何从字节转换为字符串然后再次返回,对吗?
Coray13年

2
解决该问题的答案实际上被标记为答案。从记忆中看,这并不像您建议的那么简单。请参阅Yanick的答案,我认为您误解了我的要求,但感谢您的投入。
0909EM 2013年

9
@CorayThan实际上,这根本无法解决OP的问题。如果您实际阅读了一下,您会发现byte[]他正在接收的代表为String;即"[97, 98, 99]"不是[97, 98, 99]。意思是,您的答案甚至不适用于这种情况。
b1nary.atr0phy 2013年

2
你的答案是Stringbyte[]String。我认为问题的要求是byte[]Stringbyte[]
Wundwin生于2014年

13
甚至可能是对所提问题的错误回答,但这有助于我解决问题。这就是为什么人们在降级别人的回答之前应该多想一点。谢谢CorayThan!
罗伯托·桑托斯

21

我做了什么:

返回客户:

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

String str = Base64.encodeBase64String(result);

return str;

从客户那里收到:

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

您的数据将以以下格式传输:

OpfyN9paAouZ2Pw+gDgGsDWzjIphmaZbUyFx5oRIN1kkQ1tDbgoi84dRfklf1OZVdpAV7TonlTDHBOr93EXIEBoY1vuQnKXaG+CJyIfrCWbEENJ0gOVBr9W3OlFcGsZW5Cf9uirSmx/JLLxTrejZzbgq3lpToYc3vkyPy5Y/oFWYljy/3OcC/S458uZFOc/FfDqWGtT9pTUdxLDOwQ6EMe0oJBlMXm8J2tGnRja4F/aVHfQddha2nUMi6zlvAm8i9KnsWmQG//ok25EHDbrFBP2Ia/6Bx/SGS4skk/0couKwcPVXtTq8qpNh/aYK1mclg7TBKHfF+DHppwd30VULpA== 

7

什么Arrays.toString()是在byteArray中创建每个字节的字符串表示形式。

请检查API文档 Arrays API

要将响应字符串转换回原始字节数组,您必须使用split(",")或某种东西并将其转换为一个集合,然后将其中的每个单个项目转换为一个字节以重新创建字节数组。


5

在Java中将字节数组转换为字符串并将字符串转换回字节数组很简单。我们需要知道何时以正确的方式使用“新”。可以按照以下步骤完成:

字节数组到字符串的转换:

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

字符串到字节数组的转换:

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

有关更多详细信息,请参见:http : //evverythingatonce.blogspot.in/2014/01/tech-talkbyte-array-and-string.html


2
不,您尚未阅读问题,或者您可能尚未理解问题。您会注意到,问题在几年前就得到了回答……
0909EM 2014年

3

您从字节数组([B@405217f8)中看到的输出类型也是零长度字节数组(即new byte[0])的输出。看起来该字符串是对数组的引用,而不是对数组内容的描述,就像我们可能从常规集合的toString()方法中。

与其他答复者一样,我将向您String指出接受byte[]参数以从字节数组的内容构造字符串的构造函数。InputStream如果要从TCP连接获取字节,则应该能够从套接字读取原始字节。

如果您已经String使用(InputStreamReader)读取了这些字节,则可以使用getBytes()函数将字符串转换为字节。确保将所需的字符集传递给String构造函数和getBytes()函数,这仅在字节数据可以通过转换为字符时才有效InputStreamReader

如果要处理原始字节,则应真正避免使用此流读取器层。


2

您不仅可以将字节作为字节发送,还是可以将每个字节转换为字符并作为字符串发送?如果只有11个字节要发送,则按原样执行操作将在字符串中至少占用85个字符。您可以创建字节的字符串表示形式,因此它将是“ [B @ 405217f8””,可以轻松地将其转换为Python中的bytesbytearray对象。否则,您可以将它们表示为一系列十六进制数字(“ 5b42403430353231231638638”),它们占22个字符,可以使用轻松在Python端对其进行解码binascii.unhexlify()


1
[B@405217f8是数组的Java对象ID,而不是数组的内容。对象ID当然不能 “轻松地在python中转换为字节或字节数组对象”。在大小上最好的办法是将byte []转换为base64字符串。
鲍里斯·B

没错,我天真的假设0909EM足够了解对象的(类型化的)地址和对象的内容。
2012年


1

如果要将字符串转换回字节数组,则需要使用String.getBytes()(或等效的Python函数),这将允许您打印出原始字节数组。


0

使用以下代码API将字节码作为字符串转换为Byte数组。

 byte[] byteArray = DatatypeConverter.parseBase64Binary("JVBERi0xLjQKMyAwIG9iago8P...");

-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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.