java - 字节数组到字符串并返回.. -127 的问题

标签 java scala

如下:

 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)

所以,总结一下:StringArray[Byte] 之间的转换涉及编码和解码。如果要将二进制数据放入字符串中,则必须在字符级别进行。但是请注意,这会给你一个垃圾字符串(即结果不会是格式正确的 UTF-16,因为 String 应该是这样),所以你最好把它读出来作为字符并将其转换回字节。

可以将字节向上移动,例如添加 512;然后你会得到一堆有效的单个 Char 代码点。但这是使用 16 位来表示每 8 位,即 50% 的编码效率。 Base64 是序列化二进制数据的更好选择(8 位表示 6,效率为 75%)。

关于java - 字节数组到字符串并返回.. -127 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5250324/

相关文章:

java - 从java中的elasticsearch查询返回一定数量的文档

scala - spark/scala 在任何列中删除带有 nan 的行

scala:方法的返回值并过早地结束该方法

java - 使用java ConcurrentSkipListSet add方法时线程卡住

java - 无法找到直观的良好实践背后的设计/编程习语 : give your object construction a deterministic period

java - 在 JAVA 中针对很长的请求实现 SOAP 客户端的良好实践?

java - 系统记录器是否使用计算机资源?

scala - 如何使 sbt 任务使用特定的配置范围?

scala - Hadoop 端口 : fs. default.name

java - Eclipse 悬停在变量黑屏上