ChatGPT解决这个技术问题 Extra ChatGPT

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

我试图理解一个字节[]到字符串,字节[]到字节[]转换的字符串表示......我将我的字节[]转换为要发送的字符串,然后我期待我的网络服务(用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

这两个都与我发送的数据不同......我确定我错过了一些真正简单的东西......

有什么帮助吗?!

请注意,通常您会使用字节的 base 64 编码 (0QEQVAJlblNvbWUgTkZDIERhdGE=) 或十六进制编码 (d101105402656e536f6d65204e46432044617461);不是带有分隔符,疣和诸如此类的数组编码。所以这个 Q/A 是 - 或不应该 - 适用于 99% 的情况。请注意,TCP 和 HTTP 完全能够使用 POST 处理大量数据的二进制文件。

B
Boann

您不能只获取返回的字符串并从中构造一个字符串......它不再是 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 保存 array b1 的字符串表示,而 s2 保存 b1 中包含的 bytes 的字符串表示。

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


惊人的!我想你已经完全理解了我所追求的......我不是来自 Java 背景,所以我无法真正弄清楚我需要的转换。仅供参考,我将 s1 发送到服务器,并且服务器正在回复 s1(我可以验证服务器是否收到并回复了 s1 中的数据),所以我确实需要 Arrays.toString() 的反面你建议......而且你的解决方案非常好!干杯!
谢谢雅尼克。但它为每个图像循环 2046 次,因为 bytes.length 的值为 2046。还有其他方法可以做到这一点吗?
如果您收到的数据真的是一个人类可读的字符串,需要像我的答案中的变量 response 的值一样进行解析,那么不幸的是,没有,没有其他方法。最好的方法是让您将字节作为原始数据(作为二进制)而不是字符串接收,或者甚至作为 Base64 字符串接收,这只需要您将其转换回基本 256(二进制)值。
要添加其他正确(尽管不完整)的答案:1)在Java中转换为字符串的任何字节[]数组都应指定字符集。 byte[] 数组是 UTF-8 还是其他?不具体或不知道它是什么会产生错误。 2) Java 使用 Big-Endian 编码,但 M$ 系统例如使用 Little-Endian。在处理字符串(基于字符)的 byte[] 数组时,没问题。但是,如果 byte[] 数组表示一个数字,则源/目标系统的“字节顺序”很重要。
C
CorayThan
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

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

这很容易。


如此多的反对票,但解释如此之少......我所说的行不通吗?当我使用它时它起作用了,问题是如何从字节转换为字符串然后再转换回来,对吗?
解决这个问题的答案实际上被标记为答案。从记忆来看,它并不像您建议的那么简单...请参阅 Yanick 的回答,我认为您误解了我的要求,但感谢您的输入。
@CorayThan实际上不,这根本没有解决OP的问题。如果您真正通读它,您会看到他收到的 byte[] 表示为 String;即 "[97, 98, 99]" 不是 [97, 98, 99]。意思是,您的答案甚至不适用于这种情况。
您的答案是 Stringbyte[]String。我认为问题要求是 byte[]Stringbyte[]
甚至可能是对所提问题的错误回答,但它帮助我解决了问题。这就是为什么人们在降级别人的回复之前应该多考虑一下。谢谢科雷坦!
S
Saorikido

我做了什么:

返回给客户:

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== 

b
bluish

Arrays.toString() 的作用是为您的 byteArray 中的每个单独字节创建一个字符串表示形式。

请查看 API 文档Arrays API

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


U
Ulrich Thomas Gabor

在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


不,您没有阅读该问题,或者您可能没有理解该问题。正如您会注意到的那样,这个问题在几年前就得到了回答......
L
Littm

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

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

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

如果你想处理原始字节,你应该避免使用这个流阅读器层。


J
JAB

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


[B@405217f8 是数组的 Java 对象 ID,而不是数组的内容。对象 ID 当然不能“在 python 中很容易转换为字节或字节数组对象”。您可以按大小做的最好的事情是将 byte[] 转换为 base64 字符串。
你是对的,我天真地假设 0909EM 知道足以区分对象的(键入的)地址和对象的内容。
P
Patricio Córdova

[JDK8]

import java.util.Base64;

要字符串:

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

到字节数组:

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

b
bluish

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


A
Ajay Kumar

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

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

3
3logy

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

V
Vinay Kumar P.V.

您可以执行以下操作将字节数组转换为字符串,然后将该字符串转换为字节数组:

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

但是要将字符串转换为字节数组,然后将该字节数组转换为字符串,可以使用以下方法:

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

我也在以下问题中回答了同样的问题:https://stackoverflow.com/a/70486387/17364272