7

我从 UTF-8 编码的流中读取了一些数据

String line = new String(byteArray, "UTF-8");

然后尝试找到一些子序列

int startPos = line.indexOf(tag) + tag.length();
int endPos   = line.indexOf("/", startPos);

剪下来

String name = line.substring(startPos, endPos);

在大多数情况下,它工作正常,但有时结果会被破坏。例如,对于像我这样的输入名称,我得到了,"гордунни"等值。似乎代理对由于某种原因被随机破坏。我在 1000 次中得到了 4 次。"горд��нни""горду��ни""г��рдунни"

如何解决?我是否需要使用其他 String 方法而不是 indexOf()+substring() 或对我的结果使用一些编码/解码魔法?

4

2 回答 2

1

出现问题是因为流被读取为字节块,有时会拆分多字节 UTF-8 字符。

通过将 InputStream 包装在 InputStreamReader 中,您将读取字符块(而不是字节块),并且多字节 UTF-8 字符将继续存在。

于 2014-07-15T06:59:51.907 回答
0

在您的示例中,您可以显示 byteArray、line 和 tag 的内容吗?您能否也显示将获得什么长度,什么 startPos 和什么 endPos?我的意思是,在字符串“гордунни”中没有“/”!为什么要计算 endPos?标签内的字符串是什么?您确定子字符串的第二个参数是 endpos 而不是长度吗?确实,“гордунни”不需要代理对,因为所有代码点都低于 0xFFFF,但是一旦在您的 utf-16 字符串中的某个地方至少有一个代理对,我敢打赌字符串的长度会给您单词的数量元素而不是代码点的数量。我不确定 Java,但在 C# 中,长度为您提供了元素的数量。要获取字符/代码点的数量,您必须使用 C# 中的 StringInfo 类。还要检查你是否' 你的字符串中会有一些 BOM。什么是


String line = new String(byteArray, "UTF-8");

正在做?字节数组是否是一个 utf-8 编码的字符串被转换为 utf-16?它是否包含 utf-8 BOM?之后的字符串是否有 utf-16LE 或 utf-16BE BOM?

于 2014-01-22T18:10:48.480 回答