Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java字符串包含无关数据_Java_String_Parsing_Encoding_Numbers - Fatal编程技术网

Java字符串包含无关数据

Java字符串包含无关数据,java,string,parsing,encoding,numbers,Java,String,Parsing,Encoding,Numbers,我有一个UTF16LE编码的输入。当这个输入到达我的代码时,它已经通过了一个FileInputStream,这个FileInputStream封装在一个LineNumberReader中的文件读取器中 读取的第一行给出如下字符串: “像字符串一样的一段数据” 但是,查看此字符串时,值将大致如下所示: [, 1, p, i, ...] 所以整根绳子还在里面 在任何情况下,它都会返回一个ParseException,我会将不可解析的号码打印到一条异常消息中,我的日志告诉我“1”是一个不可解析的号码

我有一个UTF16LE编码的输入。当这个输入到达我的代码时,它已经通过了一个FileInputStream,这个FileInputStream封装在一个LineNumberReader中的文件读取器中

读取的第一行给出如下字符串:

“像字符串一样的一段数据”


但是,查看此字符串时,值将大致如下所示:

[, 1, p, i, ...]

所以整根绳子还在里面

在任何情况下,它都会返回一个
ParseException
,我会将不可解析的号码打印到一条异常消息中,我的日志告诉我“1”是一个不可解析的号码

真正的问题似乎是前导空元素,因为后续的行显示了类似的行为,除了前导空元素,它们进行解析。

一个
字符串(至少是OpenJDK中的实现)存储一个
char[]
、一个偏移量和一个计数。
字符串的实际内容是
char[]
中的字符,索引为
offset
offset+count

这意味着
char[]
可以容纳比
字符串实际代表的更多的字符

这样做是为了能够在不同的
String
实例之间共享
char[]
s

例如,如果您有一个值为
foobar
字符串
,并在其上调用
.substring(3)
,则生成的
字符串
将表示
,但它们实际上可能引用相同的
字符[]
。第二个
字符串
的偏移量将比原始
字符串
大3,而
计数
则小3

所有这一切之所以有效,是因为
String
对象确实是不可变的:因为没有一个
String
会以任何方式修改它的
char[]
,所以它们共享它是完全安全的


这意味着在调试器中检查
字符串
对象可能会产生错误的印象。因此,如果要逐个字符检查
字符串
最安全的方法是调用其中一个或在循环中调用。

我想我已经找到了答案。编码不是UTF16LE。通过自动字符检测算法将其设置为UTF16LE。编码为utf16,带有BOM表。然而,由于不同的类认为编码是UTF16LE,因此它们并没有摆脱不应该出现在LE版本中的BOM。

“然而,查看此字符串时,值将是沿着:[,1,p,i,…]的行的。这没有道理。您是如何识别字符串的元素的?Java字符串是
char
s的序列,没有“空char”这样的东西。调试时您到底看到了什么?正如sleske所建议的,“empty”元素实际上并不是空的。您应该打印出它的数值,以查看它是什么代码点。我的猜测是,它可能与BOM有关……这可能是一个BOM(我应该将其添加到我的故事中),但UTF16LE不允许有BOM,因为LE已经说过了。即使如此,解析器编码还是显式地设置为UTF16LE。我通过eclipse调试器识别了字符串的内容,我写的是eclipse所说的内容。调试的一种方法是迭代字符串,使用string.getChar(index)获取单个
char
s。然后使用字符串((int)c)打印每个
char
。转换为int将为您提供字符的数值(即Unicode代码点)。@Jasper:并且永远不要盲目相信调试器:-)。谢谢,非常清楚。不幸的是,这意味着添加调试器应该替换的调试代码。贾斯珀:好的,
字符串
显示屏在99%的时间内显示正确和准确的值(即每次
字符串
只包含可打印的字符)。另一次,您应该能够在所选的调试器中直接执行小代码段:无需将它们添加到生产代码中。顺便说一句,gvim还将该文件标识为UTF16LE,而不是UTF16LE。我没有创建源文件,也不能期望在测试环境之外,我不得不更多地猜测编码。 [, 1, p, i, ...]