字节数组到String并返回..问题-127

Jus*_*s12 32 java scala

在下面的:

 scala> (new String(Array[Byte](1, 2, 3, -1, -2, -127))).getBytes
 res12: Array[Byte] = Array(1, 2, 3, -1, -2, 63)
Run Code Online (Sandbox Code Playgroud)

为什么-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
Run Code Online (Sandbox Code Playgroud)

Rex*_*err 50

你正在调用的构造函数使得二进制到字符串的转换使用解码是不明显的: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)
Run Code Online (Sandbox Code Playgroud)

因此,要总结:之间进行转换String,并Array[Byte]涉及编码和解码.如果要将二进制数据放入字符串中,则必须在字符级别执行此操作.但请注意,这将为您提供一个垃圾字符串(即结果将不是格式良好的UTF-16,如String预期的那样),因此您最好将其作为字符读出并将其转换回字节.

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


Pet*_*rey 12

字符串用于存储文本而非二进制数据.

在你的默认字符编码中,-127没有字符,所以它用'?'替换它 或63.

编辑:Base64是最好的选择,更好的是不使用文本来存储二进制数据.它可以完成,但不能使用任何标准字符编码.即你必须自己做编码.

要按字面意思回答您的问题,您可以使用自己的字符编码.这是一个非常糟糕的主意,因为任何文本都可能以您看到的相同方式进行编码和修改.使用Base64可以通过使用任何编码都安全的字符来避免这种情况.

byte[] bytes = new byte[256];
for (int i = 0; i < bytes.length; i++)
    bytes[i] = (byte) i;
String text = new String(bytes, 0);
byte[] bytes2 = new byte[text.length()];
for (int i = 0; i < bytes2.length; i++)
    bytes2[i] = (byte) text.charAt(i);
int count = 0;
for (int i = 0; i < bytes2.length; i++)
    if (bytes2[i] != (byte) i)
        System.out.println(i);
    else
        count++;
System.out.println(count + " bytes matched.");
Run Code Online (Sandbox Code Playgroud)


hof*_*ff2 9

StringOps有一个方法getBytes,我认为这可能是将String转换为Array [Byte]的实际需要

http://www.scala-lang.org/api/2.10.2/index.html#scala.collection.immutable.StringOps


cod*_*dez 5

使用正确的字符集:

scala> (new String(Array[Byte](1, 2, 3, -1, -2, -127), "utf-16")).getBytes("utf-16")
res13: Array[Byte] = Array(-2, -1, 1, 2, 3, -1, -2, -127)
Run Code Online (Sandbox Code Playgroud)