String.getBytes()的结果是否包含零?

时间:2016-01-03 04:30:39

标签: java

我尝试了很多带有随机字符的字符串,除了空字符串“”外,它们的.getBytes()字节数组似乎从不包含任何0值(如{123,-23,54,0,-92})。

除了空字符串外,它们的.getBytes()字节数组总是不包含nero吗?

编辑:以前的测试代码如下。现在我了解到,在Java 8中,如果String由(char)random.nextInt(65535)+ 1组成,结果似乎总是“不包含0”;如果String包含(char)0,则“包含0”。

WindowSnap

2 个答案:

答案 0 :(得分:7)

它取决于您的平台本地编码。但是在许多编码中,'\0'(null)字符将导致getBytes()返回一个零的数组。

System.out.println("\0".getBytes()[0]);

这适用于US-ASCII,ISO-8859-1和UTF-8编码:

System.out.println("\0".getBytes("US-ASCII")[0]);
System.out.println("\0".getBytes("ISO-8859-1")[0]);
System.out.println("\0".getBytes("UTF-8")[0]);

如果你有一个字节数组,并且你想要与之对应的字符串,你也可以这样做:

byte[] b = { 123, -23, 54, 0, -92 };
String s = new String(b);

然而,对于不同的编码,这将给出不同的结果,并且在某些编码中,它可能是无效的序列。

其中的字符可能无法打印。

最好的选择是ISO-8859-1编码,只能打印空字符:

byte[] b = { 123, -23, 54, 0, -92 };
String s = new String(b, "ISO-8859-1");
System.out.println(s);
System.out.println((int) s.charAt(3));

修改

在您发布的代码中,如果指定UTF-16编码,也很容易获得“包含0”:

byte[] bytes = s1.getBytes("UTF-16");

这都是关于编码的,你还没有指定它。如果您尚未将其作为getBytes方法的参数传递,则会采用您的平台默认编码。

要了解您平台上的内容,请运行以下命令:

System.out.println(System.getProperty("file.encoding"));

在MacOS上,它是UTF-8;在Windows上,它可能是像Cp-1252这样的Windows代码页之一。您还可以在运行Java时在命令行上指定platform default:

java -Dfile.encoding=UTF16 <the rest>

如果以这种方式运行代码,您还会看到它包含0。

答案 1 :(得分:1)

  

除了空字符串外,它们的.getBytes()字节数组总是不包含nero吗?

不,没有这样的保证。首先,最重要的是,.getBytes()使用平台的默认字符集返回“一个字节序列”。因此,defining your own custom charset无法阻止您将某些值明确编码为0 s。

更实际地,许多常见编码将包括零字节,特别是代表NUL character。但即使您的字符串不包含NUL,字节序列也可能包含0 s。特别是UTF-16Java uses internally)表示两个字节中的所有字符,这意味着ASCII字符(只需要一个)与0字节配对。

您也可以通过尝试从包含String s的字节序列构造0并使用适当的构造函数(例如String(byte[] bytes)或{{3})来自行测试。 }。例如(注意我系统的默认字符集是UTF-8):

System.out.println("Default encoding: " + System.getProperty("file.encoding"));
System.out.println("Empty string: " + Arrays.toString("".getBytes()));
System.out.println("NUL char: " + Arrays.toString("\0".getBytes()));
System.out.println("String constructed from {0} array: " +
                   Arrays.toString(new String(new byte[]{0}).getBytes()));
System.out.println("'a' in UTF-16: " +
                   Arrays.toString("a".getBytes(StandardCharsets.UTF_16)));

打印:

Default encoding: UTF-8
Empty string: []
NUL char: [0]
String constructed from {0} array: [0]
'a' in UTF-16: [-2, -1, 0, 97]