Android,日文字符文件名比较问题

2023-12-24

我正在尝试将搜索字符串与文件名与 Android 上的递归目录搜索相匹配。问题是字符是日语,在某些情况下不匹配。例如,我尝试匹配文件名开头的搜索字符串是“呼ぶ”。当我从 file.getName() 打印文件名时,这会准确反映,例如打印到控制台的文件名以“呼ぶ”开头。但是当我对搜索字符串进行匹配时,例如fileName.startwith(“呼ぶ”),不匹配。

事实证明,当我打印正在搜索的文件名的子字符串时,第二个字符是不同的——单词是“呼ふ”而不是“呼ぶ”。如果我提取字节并打印十六进制字符,则最后一个字节会减少 1 – 大概是“ぶ”和“ふ”之间的差异。

这是用于显示差异的代码:

    String name = soundFile.getName();
    String string1 = question.kanji;


    Log.d(TAG, "searching for : s1:" + question.kanji + " + " + question.hiragana + " + " + question.english);
    Log.d(TAG, "name is: " + name);

    Log.d(TAG, "question.kanaji.length(): " + question.kanji.length());
    Log.d(TAG, "question.hiragana.length(): " + question.hiragana.length());


    String compareStart = name.substring(0, string1.length() );

    Log.d(TAG, "string1.length(): " + string1.length());
    Log.d(TAG, "compareStart.length(): " + compareStart.length());      

        byte[] nameUTF8 = null; 
    byte[] s1UTF8 = null;
    byte[] csUTF8 = null;

    nameUTF8 = name.getBytes();
    s1UTF8 = string1.getBytes();
    csUTF8 = compareStart.getBytes();


    Log.d(TAG, "nameUTF8.length: " + s1UTF8.length);            
    Log.d(TAG, "s1UTF8.length: " + s1UTF8.length);
    Log.d(TAG, "csUTF8.length: " + csUTF8.length);

    for (int i = 0; i < s1UTF8.length; i++) {
        Log.d(TAG, "s1UTF8[i]: " + Integer.toString(s1UTF8[i] & 0xff, 16).toUpperCase());
    }

    for (int i = 0; i < csUTF8.length; i++) {
        Log.d(TAG, "csUTF8[i]: " + Integer.toString(csUTF8[i] & 0xff, 16).toUpperCase());
    }

    for (int i = 0; i < nameUTF8.length; i++) {
        Log.d(TAG, "nameUTF8[i]: " + Integer.toString(nameUTF8[i] & 0xff, 16).toUpperCase());
    }

部分输出如下:

D/AnswerView(12078): searching for : s1:呼ぶ + よぶ + to call out,to invite
D/AnswerView(12078): name is: 呼ぶ                                                     よぶ                 to call out,to invite.mp3
D/AnswerView(12078): question.kanaji.length(): 2
D/AnswerView(12078): question.hiragana.length(): 2
D/AnswerView(12078): string1: 呼ぶ
D/AnswerView(12078): compareStart: 呼ふ
D/AnswerView(12078): string1.length(): 2
D/AnswerView(12078): compareStart.length(): 2
D/AnswerView(12078): string1.length(): 2
D/AnswerView(12078): compareStart.length(): 2
D/AnswerView(12078): nameUTF8.length: 6
D/AnswerView(12078): s1UTF8.length: 6
D/AnswerView(12078): csUTF8.length: 6
D/AnswerView(12078): s1UTF8[i]: E5
D/AnswerView(12078): s1UTF8[i]: 91
D/AnswerView(12078): s1UTF8[i]: BC
D/AnswerView(12078): s1UTF8[i]: E3
D/AnswerView(12078): s1UTF8[i]: 81
D/AnswerView(12078): s1UTF8[i]: B6
D/AnswerView(12078): csUTF8[i]: E5
D/AnswerView(12078): csUTF8[i]: 91
D/AnswerView(12078): csUTF8[i]: BC
D/AnswerView(12078): csUTF8[i]: E3
D/AnswerView(12078): csUTF8[i]: 81
D/AnswerView(12078): csUTF8[i]: B5
D/AnswerView(12078): nameUTF8[i]: E5
D/AnswerView(12078): nameUTF8[i]: 91
D/AnswerView(12078): nameUTF8[i]: BC
D/AnswerView(12078): nameUTF8[i]: E3
D/AnswerView(12078): nameUTF8[i]: 81
D/AnswerView(12078): nameUTF8[i]: B5
D/AnswerView(12078): nameUTF8[i]: E3
D/AnswerView(12078): nameUTF8[i]: 82
D/AnswerView(12078): nameUTF8[i]: 99
D/AnswerView(12078): nameUTF8[i]: 20
D/AnswerView(12078): nameUTF8[i]: 20
D/AnswerView(12078): nameUTF8[i]: 20
D/AnswerView(12078): nameUTF8[i]: 20

显示提取的文件名子字符串的第六个字节以及文件名本身是“B5”,而不是搜索字符串中的“B6”。但是,打印的文件名可以正确显示。我很困惑。当底层字符不同时,为什么文件名能够正确显示到控制台?为什么文件名开头有额外的 3 个非空白字节 - 搜索字符串中不需要这些字节来表示“ぶ”字符?


该问题看起来是标准化形式之一。例如,我知道在 Mac 上,文件系统始终位于 NFD 中。但你发布的字符串是在 NFC 中。手表:

% cat /tmp/u
呼ぶ

% uwc /tmp/u
   Paras    Lines    Words   Graphs    Chars    Bytes File
       0        1        1        3        3        7 /tmp/u

% uniquote -v  /tmp/u
\N{CJK UNIFIED IDEOGRAPH-547C}\N{HIRAGANA LETTER BU}

% nfd /tmp/u | uniquote -v
\N{CJK UNIFIED IDEOGRAPH-547C}\N{HIRAGANA LETTER HU}\N{COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK}

% nfc /tmp/u | uniquote -v
\N{CJK UNIFIED IDEOGRAPH-547C}\N{HIRAGANA LETTER BU}

所以我认为你必须考虑转换为 NFD。

顺便说一句,U+547C CJK 代码点恰好是来自 Unihan 数据库的:

 呼 U+547C Lo Han    CJK UNIFIED IDEOGRAPH-547C
  Mandarin     hu1 xu1
  Cantonese    fu1
  JapaneseKun  yobu
  JapaneseOn   ko
  Korean       ho
  HanyuPinlu   hu1(378) hu5(107)
  Vietnamese   hô
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android,日文字符文件名比较问题 的相关文章

随机推荐

  • 如何使用 robolectric 对 Android 音频录制应用程序进行单元测试

    我只是想知道是否可以使用 Robolectric 框架对 Android 录音机应用程序进行单元测试 据我所知 Robolectric 没有使用模拟器或真实设备进行测试 但是在录音应用程序中 我需要测试音频是否被录制 它是否存储在SD卡上的
  • Spotify Embed iFrame 仅播放歌曲预览

    在我的网站上 即使我登录了 Spotify Premium 我似乎也只能在 Chrome 和 Safari 中播放播放列表中的曲目预览 不过 完整曲目可以在 Firefox 中播放 为什么会出现这种情况呢 这是我的网站 www studif
  • 全屏模式下的 JInternalFrame

    我打算在全屏模式下使用 JInternalFrame 作为模态 JDialog 但是 当前在调用它时并未显示它 我需要将其添加到某个容器中吗 我尝试将其添加到 JOptionPane showInternalMessage 但由于我想让对话
  • 即席查询、存储过程、动态 SQL [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • PHP - 简单 XML - 嵌套层次结构

    我一直在使用 PHP 的简单 XML 函数来处理 XML 文件 下面的代码适用于简单的 XML 层次结构 xml simplexml load file test xml echo xml gt getName br foreach xml
  • 从 pandas 数据框中减去两列并将结果存储在第三列中[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我有一个数据框 df 有 3 列 我想执行减法如下 df available df recommended df man
  • 使用 class.forname 但想要自动装配目标类的成员

    我有这个需求 我的框架的方式是从配置文件中以字符串形式读取类名 我想使用该类中的方法 显而易见的解决方案是使用反射 我已经使用了反射并能够调用我想要的方法 但问题是目标类内的变量没有自动装配 我知道我不会让 spring 通过使用反射来自动
  • 如何将 system() 调用结果的每一行写入 Vimscript 中的列表?

    我想使用 Vimscript 循环遍历目录中的文件 阅读usr 41 txt四处搜寻后 我能想到的最好的办法就是let dir contents system ls 但是由于system 没有返回列表 我无法循环它 有没有办法可以将系统调用
  • ActiveWorkbook.Connections("x").Refresh 完成时执行的代码

    从外部源选择数据我有一个数据连接 它使用select使用 vba 代码从 SQL 服务器查询到 Excel 工作表 如下所示 With ActiveWorkbook Connections x OLEDBConnection Backgro
  • Hadoop HDFS 中块的概念

    我对 Hadoop 中的块有一些疑问 我读到 Hadoop 使用 HDFS 来创建特定大小的块 第一个问题这些块是否物理存在于普通文件系统 如 NTFS 的硬盘上 即我们可以看到托管文件系统 NTFS 上的块还是只能使用 hadoop 命令
  • Perl 就地编辑:在 X12850 格式的文件中查找和替换

    我是 Perl 新手 无法弄清楚这一点 我有一个名为Test ISA 00 00 01 SupplyScan 01 NOVA 180815 0719 U 00204 000000255 0 P GS PO SupplyScan NOVA 2
  • 如何在 Android Studio 中删除代码格式中不必要的空白行

    是否可以在 Android Studio 中删除代码格式中不必要的空白行 Yes It is possible to configure the number of blank lines in the settings menu File
  • Oracle JET:淘汰赛未更新变量

    我有以下 oracle jet 和淘汰赛 html 文件
  • 以编程方式设置 type="file" 输入 HTML 元素的值? [复制]

    这个问题在这里已经有答案了 Note 下面的答案反映了 2009 年旧版浏览器的状态 现在 您实际上可以在 2017 年使用 JavaScript 动态 编程地设置文件输入元素的值 有关详细信息以及演示 请参阅此问题中的答案 如何以编程方式
  • 为自定义驱动程序创建 GraphicsDevice

    我正在开发一个在嵌入式系统中使用 Java 的项目 我有用于屏幕和触摸输入的驱动程序 以及用于文本输入的虚拟键盘 我的屏幕驱动程序有一个Graphics2D您可以绘制的对象和repaint Rectangle 更新方法 类似地 触摸驱动器能
  • 将所有函数保存在txt文件中

    我通常会运行大量模拟R 在模拟之间 R 的某些部分 代码会改变 通常情况下 我会站在旁边 模拟结果包含以下内容的 txt 文件 其中使用的每个函数的定义 模拟 为了制作该 txt 文件 我只需 运行这一行 for j in 1 length
  • 开始学习 JavaFX 之前需要了解什么? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我读到了 JavaFX 相对于 Swing 的优势 这不是讨论的重点 我想学习 JavaFX 但后来我对 JavaFX 脚本和 XML
  • Android Square Picasso 无法加载土耳其字符图像 url

    我尝试使用 square picasso 一个网络应用程序 但是如果我的图片网址包含土耳其字符 毕加索未加载 该网址正在运行 http www bulenttiras com wp content uploads 2014 02 kokhu
  • 虚拟类中的抽象方法

    我有一个 C 类 它有很多虚拟方法 其中一些方法本质上是抽象的 它们在子类中完全实现 基类是空的 为了让它编译 我在基类中抛出一个 InvalidOperationException 并注释应该做什么 这只是感觉很脏 有更好的方法来设计我的
  • Android,日文字符文件名比较问题

    我正在尝试将搜索字符串与文件名与 Android 上的递归目录搜索相匹配 问题是字符是日语 在某些情况下不匹配 例如 我尝试匹配文件名开头的搜索字符串是 呼 当我从 file getName 打印文件名时 这会准确反映 例如打印到控制台的文