如下:
scala> (new String(Array[Byte](1, 2, 3, -1, -2, -127))).getBytes
res12: Array[Byte] = Array(1, 2, 3, -1, -2, 63)
为什么 -127 转换为 63?以及如何将其恢复为 -127
[编辑:] 下面的 Java 版本(表明它不仅仅是一个“Scala 问题”)
c:\tmp>type Main.java
public class Main {
public static void main(String [] args) {
byte [] b = {1, 2, 3, -1, -2, -127};
byte [] c = new String(b).getBytes();
for (int i = 0; i < 6; i++){
System.out.println("b:"+b[i]+"; c:"+c[i]);
}
}
}
c:\tmp>javac Main.java
c:\tmp>java Main
b:1; c:1
b:2; c:2
b:3; c:3
b:-1; c:-1
b:-2; c:-2
b:-127; c:63
最佳答案
您调用的构造函数使得二进制到字符串的转换使用解码变得不明显:String(byte[] bytes, Charset charset)
。您想要的是根本不使用解码。
幸运的是,有一个构造函数:String(char[] value)
.
现在你有一个字符串中的数据,但你希望它完全按原样返回。但猜猜怎么了! getBytes(Charset charset)
没错,还有一个自动应用的编码。幸运的是,有一个 toCharArray()
方法。
如果必须以字节开头并以字节结尾,则必须将 char 数组映射到字节:
(new String(Array[Byte](1,2,3,-1,-2,-127).map(_.toChar))).toCharArray.map(_.toByte)
所以,总结一下:String
和 Array[Byte]
之间的转换涉及编码和解码。如果要将二进制数据放入字符串中,则必须在字符级别进行。但是请注意,这会给你一个垃圾字符串(即结果不会是格式正确的 UTF-16,因为 String
应该是这样),所以你最好把它读出来作为字符并将其转换回字节。
您可以将字节向上移动,例如添加 512;然后你会得到一堆有效的单个 Char
代码点。但这是使用 16 位来表示每 8 位,即 50% 的编码效率。 Base64 是序列化二进制数据的更好选择(8 位表示 6,效率为 75%)。
关于java - 字节数组到字符串并返回.. -127 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5250324/