【发布时间】:2019-09-06 00:33:42
【问题描述】:
我有需要写入 Google BigQuery 的包含各种字符的字符串,这需要严格的 UTF8 字符串。尝试使用各种表情符号输入编写字符串时,出现错误:
java.lang.IllegalArgumentException: Unpaired surrogate at index 3373
at org.apache.beam.sdk.repackaged.com.google.common.base.Utf8.encodedLengthGeneral(Utf8.java:93)
at org.apache.beam.sdk.repackaged.com.google.common.base.Utf8.encodedLength(Utf8.java:67)
at org.apache.beam.sdk.coders.StringUtf8Coder.getEncodedElementByteSize(StringUtf8Coder.java:145)
...
我有一个解决这个问题的方法,只需从字符串中删除所有代理字符:
private static String removeSurrogates(String query) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < query.length(); i++) {
char c = query.charAt(i);
if (!(Character.isHighSurrogate(c) || Character.isLowSurrogate(c))) {
sb.append(c);
}
}
return sb.toString();
}
然而,这会产生一个类似
的字符串???????????????????????????????⚔⌨??????⛳?????????? ?????????????????????????????????????????????⛏??????
减少到只有四个表情符号
⚔⌨⛳⛏
是否有适当的方法将这些字符转换为 UTF8 而不会丢失,并且不使用不成对的代理?
(抱歉,我对一般字符集的理解不是很好)
【问题讨论】:
-
编码为 UTF8?
-
输入数据来自一个已经 UTF8 编码的文件。我们测试它是使用 com.google.protobuf.ByteString.isValidUtf8(),然后使用来自 loggedBytes.toStringUtf8() 的字符串,但是当我们尝试写入字符串时,我们会得到未配对的代理异常。
-
当您将文件读入
String时,该文件将被转换为UTF-16(Javachar)。这就是为什么你有代理对。如果你只是将它转换回来,代理对就会消失。 -
谢谢,您有如何将其转换回来的示例吗?
-
我发现了问题。我们正在使用 org.apache.commons.lang3.StringEscapeUtils.unescapeHtml4 将字符串中的 HTML 实体转换为它们的非编码形式。这似乎破坏了一些非拉丁字符。例如,传递字符串“Italien ??????????”通过这种方法将其转换为“Italien ???????” (最后一个字符被破坏)。所以,结果不是数据流或大查询问题
标签: java google-bigquery google-cloud-dataflow emoji