【问题标题】:String.startswith fails when comparing UTF-16 string to literal将 UTF-16 字符串与文字进行比较时,String.startswith 失败
【发布时间】:2018-06-05 23:52:47
【问题描述】:

我有一个 Unicode(“Windows Notepad Unicode”或 UTF-16LE)文本文件,我从中读取如下行:

    FileInputStream is = new FileInputStream(cmdFile);
    BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-16LE"));
    String line = reader.readLine();

现在我需要检查行是否以某个字符序列开头:

if (line.startsWith("[COMMAND]")) ...

但是即使 line 实际上以这个字符序列“开始”,这也会返回 false。
在检查startsWith 的源代码时,我可以看到比较是逐个字符进行的。但据我所知,Java 实际上在内部使用这种特定编码表示字符串,那么为什么比较失败呢?在这种情况下比较的正确方法是什么?
想到的一件事是将String 转换为具有所需编码的字节数组,然后比较两个字节数组,但这似乎是一种相当粗略的方法,有没有更优雅的方法?

【问题讨论】:

  • 如何创建“[COMMAND]”字符串?正如在哪种情况下写的那样,是 UTF-8 还是您正在创建一个 UTF-16LE 字符串进行比较?
  • 我的代码和我在这里写的完全一样。所以你的意思是Android在内部将字符串表示为UTF-8?从官方文档中似乎没有证实 - docs.oracle.com/javase/7/docs/api/java/lang/String.html
  • idownvotedbecau.se/nodebugging --- 使用调试查看从文件中读取的实际字符串。可能的原因:UTF-16 文本文件以BOM 开头,因此读取的第一行将以此开头。 Java Reader 类没有对 BOM 的特殊处理。请参阅:Beware of Byte Order Marks
  • 他们不比较的唯一原因是因为两个字符串不是以相同的字符开头!!!如果您使用调试器查看line 变量中字符串的实际字符,您会发现,为您自己,为什么它们不能比较. --- 不知道你用的是什么调试器。在 Eclipse 中,您只需展开字符串即可查看底层 char[],您可以在其中看到字符。
  • 仅供参考: Java 字符串是 char 值的数组。 char 值是一个 UTF-16 字符。没有关于它的LEBE,因为这完全取决于JVM。

标签: java unicode string-comparison utf-16


【解决方案1】:

经过一些研究并使用String.getBytes(),可以看出问题出在字节顺序标记或 BOM 上。 Android Studio 没有像通常那样在工具提示中将这些额外的字符显示为问号,这让我很困惑。

【讨论】:

    【解决方案2】:

    您可以尝试将line 的字符单独打印为整数,以检查字符串的实际组成方式。在我的应用程序中,我只使用了 BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 并且能够正确使用 String 的 split 方法......所以也许startsWith 也可以正常工作。

    【讨论】:

      猜你喜欢
      • 2016-03-14
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多