我试图理解一个字节[]到字符串,字节[]到字节[]转换的字符串表示......我将我的字节[]转换为要发送的字符串,然后我期待我的网络服务(用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
这两个都与我发送的数据不同......我确定我错过了一些真正简单的东西......
有什么帮助吗?!
0QEQVAJlblNvbWUgTkZDIERhdGE=
) 或十六进制编码 (d101105402656e536f6d65204e46432044617461
);不是带有分隔符,疣和诸如此类的数组编码。所以这个 Q/A 是 - 或不应该 - 适用于 99% 的情况。请注意,TCP 和 HTTP 完全能够使用 POST
处理大量数据的二进制文件。
您不能只获取返回的字符串并从中构造一个字符串......它不再是 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)
的反面,因此我粘贴在此答案的第一个片段中的代码。
String coolString = "cool string";
byte[] byteArray = coolString.getBytes();
String reconstitutedString = new String(byteArray);
System.out.println(reconstitutedString);
这会将“酷字符串”输出到控制台。
这很容易。
byte[]
表示为 String
;即 "[97, 98, 99]"
不是 [97, 98, 99]
。意思是,您的答案甚至不适用于这种情况。
String
到 byte[]
到 String
。我认为问题要求是 byte[]
到 String
到 byte[]
。
我做了什么:
返回给客户:
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==
Arrays.toString()
的作用是为您的 byteArray 中的每个单独字节创建一个字符串表示形式。
请查看 API 文档Arrays API
要将您的响应字符串转换回原始字节数组,您必须使用 split(",")
或其他东西并将其转换为一个集合,然后将其中的每个单独项目转换为一个字节以重新创建您的字节数组。
在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
您从字节数组 ([B@405217f8
) 看到的输出类型也是零长度字节数组(即 new byte[0]
)的输出。看起来这个字符串是对数组的引用,而不是对数组内容的描述,就像我们对常规集合的 toString()
方法所期望的那样。
与其他受访者一样,我会向您指出接受 byte[]
参数的 String
构造函数,以根据字节数组的内容构造字符串。如果您想从 TCP 连接获取字节,您应该能够从套接字的 InputStream
读取原始字节。
如果您已将这些字节作为 String
读取(使用 InputStreamReader
),则可以使用 getBytes()
函数将字符串转换为字节。确保将所需的字符集同时传递给 String 构造函数和 getBytes()
函数,这只有在字节数据可以通过 InputStreamReader
转换为字符时才有效。
如果你想处理原始字节,你应该避免使用这个流阅读器层。
您可以不只是将字节作为字节发送,或者将每个字节转换为字符并作为字符串发送吗?当您只有 11 个字节要发送时,像您一样执行此操作将占用字符串中的至少 85 个字符。您可以创建字节的字符串表示形式,因此它是“[B@405217f8”,可以在 Python 中轻松转换为 bytes
或 bytearray
对象。否则,您可以将它们表示为占用 22 个字符的一系列十六进制数字(“5b42403430353231376638”),可以在 Python 端使用 binascii.unhexlify()
轻松解码。
[B@405217f8
是数组的 Java 对象 ID,而不是数组的内容。对象 ID 当然不能“在 python 中很容易转换为字节或字节数组对象”。您可以按大小做的最好的事情是将 byte[] 转换为 base64 字符串。
[JDK8]
import java.util.Base64;
要字符串:
String str = Base64.getEncoder().encode(new byte[]{ -47, 1, 16, ... });
到字节数组:
byte[] bytes = Base64.getDecoder().decode("JVBERi0xLjQKMyAwIG9iago8P...");
如果要将字符串转换回字节数组,则需要使用 String.getBytes()
(或等效的 Python 函数),这将允许您打印出原始字节数组。
使用以下代码 API 将字节码作为字符串转换为字节数组。
byte[] byteArray = DatatypeConverter.parseBase64Binary("JVBERi0xLjQKMyAwIG9iago8P...");
[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);
您可以执行以下操作将字节数组转换为字符串,然后将该字符串转换为字节数组:
// 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
不定期副业成功案例分享
response
的值一样进行解析,那么不幸的是,没有,没有其他方法。最好的方法是让您将字节作为原始数据(作为二进制)而不是字符串接收,或者甚至作为 Base64 字符串接收,这只需要您将其转换回基本 256(二进制)值。