--我想将ByteArray转换为string,然后将该字符串转换为ByteArray,但在转换值时发生了更改。有人帮助解决这个问题。
person.proto:
syntax = "proto3";
message Person{
string name = 1;
int32 age = 2;
}编译后,它给出案例类人员(由google在编译时创建)
我的MainClass:
val newPerson = Person(
name = "John Cena",
age = 44 //output
)
println(newPerson.toByteArray) //[B@50da041d
val l = newPerson.toByteArray.toString
println(l) //[B@7709e969
val l1 = l.getBytes
println(l1) //[B@f44b405为什么值会改变??如何正确转换??
发布于 2022-02-23 17:01:30
[B@...是JVM字节数组的.toString返回的格式,它只是[B (意思是“字节数组”)和一个十六进制字符串,它类似于数组所在的内存地址(我故意不称它为指针,但它类似;十六进制字符串到内存地址的精确映射依赖于JVM,可能会受到使用中的垃圾收集器之类的东西的影响)。重要的是,两个具有相同字节的不同数组将具有不同的.toString。请注意,在某些地方(例如REPL),Scala将打印类似于Array(-127, 0, 0, 1)的东西,而不是调用.toString:这可能会导致混淆。
似乎每次调用toByteArray都会发出一个新的数组。因此,当您第一次调用newPerson.toByteArray时,您将在与50da041d对应的位置得到一个数组。第二次调用它时,在与7709e969对应的位置得到一个具有相同内容的字节数组,并将字符串[B@7709e969保存到变量l中。然后,当您对该字符串调用getBytes (将其保存在l1中)时,将得到一个字节数组,该数组是与f44b405对应的位置上的字符串"[B@7709e969“的编码。
因此,在与50da041d和7709e969对应的位置,您有两个不同的字节数组,它们恰好包含相同的元素(这些元素是newPerson的原始表示中的字节)。在与f44b405对应的位置,您有一个字节数组,其中字节编码(在某些字符集中,可能是UTF-16?) [B@7709e969。
因为proto并不是真正的字符串,所以没有获得有用字符串的一般方法(取决于您所处理的有用的定义)。您可以尝试将toByteArray中的字节数组解释为具有给定字符编码的字符串,但不能保证任何给定的proto在任意字符编码中都是有效的。
一个纯粹是8位的编码,比如ISO-8859-1,至少可以从字节数组中解码,但是可能有不可打印或控制的字符,所以不太可能这样做:
val iso88591Representation = new String(newPerson.toByteArray, java.nio.charset.StandardCharsets.ISO_8859_1)或者,您可能需要像Scala将(有时)呈现它那样的表示:
"Array(" + newPerson.toByteArray.mkString(", ") + ")"https://stackoverflow.com/questions/71237426
复制相似问题