栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【java】中文转拼音遇到的奇葩事件

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【java】中文转拼音遇到的奇葩事件

背景

公司线上业务有报错,截图找不到了。总之,就是有些生僻字,用pinyin4这个工具包是找不到的,然后抛出空指针。

时间线

    生僻字无法转换拼音,说起来也是非常无语的。第一反应是升级工具包吧,拼音翻译的工具包升级应该也就是为了规避生僻字吧,于是吧maven升级了一下。但是发现..并没有用。没用那就看看文档喽,对比了好多转换拼音的工具包。emm 找到链接后补充吧,总之是经过多方对比,发现jpinyin很好。

还有一点就是对于无法找到拼音的汉字,会直接返回本字体,起码不会报错。于是更改了工具包,重新引入。又外挂了本项目路径下的字典,添加了日志中发现的特别的字。

    代码提交后,组长觉得有问题.. 因为他看了 jpinyin和pinyin4的github,发现jpinyin的star数过低..认为风险很大..说两个都查才是最好的.. 怪我,我没有把对比的方案写出来(不过写出来好像也没啥用。后来想想还是算了,我又改回了原有的pinyin4,更改了原来的代码,实在找不到再用jpinyin找一下. okok. 再原有逻辑下,又添加了外挂字典。不是很懂为啥要这么复杂..

请记住外挂了字典,接下来戏剧开始了..

static {
    MultiPinyinConfig.multiPinyinPath= Objects.requireNonNull(ChineseToSpellManagerImpl.class.getClassLoader().getResource("userPinyin.txt")).getPath();
}
    发到测试环境,没有翻译成功,没有找到对应的拼音。直接更新的是原有汉字。考虑没有读取到外挂文件。我们的项目用的是dropwized,这个框架,蛮特别的,可以看下此文章介绍。

Dropwizard框架入门 - 云+社区 - 腾讯云

我们的项目是部署在docker容器中的,目前的流程是dropwized会打包jar,然后docker拉取镜像,然后进行部署启动。再此过程中,找不到文件是很很正常的,因为容器中并没有文件路径。于是参考了下文章去想办法在容器中添加目录,挂载文件。

docker下读取txt文件找不到路径,必须copy到容器或者映射文件 - 代码先锋网

    找到了运维,他是一次次的加路径改项目,最后找到了文件,也可以按照我的想法执行,但是发现致命的问题。
      项目应用过多,若用docker挂载,需要在每个应用配置文件添加,日后还会私有化部署,这个很不友好。现在公司还没有文件管理器,但凡要是加一个字在字典中,那就每个文件都加吧..
    基于以上的问题,又想到可以在jar包里面直接读取,不通过docker,在jar中读取文件,然后写到一个虚拟路径文件中,最后把路径交给工具包解析。于是就有了下面的代码
static {
    MultiPinyinConfig.multiPinyinPath = System.getProperty("user.dir") + "/config/userPinyin.txt";
    String line;
    BufferedReader br = new BufferedReader(
        new InputStreamReader(
            Objects.requireNonNull(ChineseToSpellManagerImpl.class.getClassLoader()
                .getResourceAsStream("userPinyin.txt"))));
    try (PrintWriter pw = new PrintWriter(new FileOutputStream(MultiPinyinConfig.multiPinyinPath))) {
        while ((line = br.readLine()) != null) {
            pw.println(line);
        }
    } catch (IOException e) {
        log.error("ChineseToSpellManager read file error.{}.", e.getMessage(), e);
    } finally {
        try {
            br.close();
        } catch (IOException e) {
            log.error("ChineseToSpellManager BufferedReader error.{}.", e.getMessage(), e);
        }
    }
}

本地测试通过,再次提交测试环境。然后maven打包过不去了.. 刚开始是认为自己pom文件写的不规范,怎么也找不到原因。

本地打包,还是不行,然后按照提示找用了findbug命令。

这个findbug工具包是指在项目打包的时候,会检测是潜在的风险点。

使用指令后,打包弹窗如下:

最后发现: 项目再打包时候,会运行static加载类文件。。因为字符的转换,没有写标准的字符。。

static {
    MultiPinyinConfig.multiPinyinPath = System.getProperty("user.dir") + "/config/userPinyin.txt";
    String line;
    BufferedReader br = new BufferedReader(
            new InputStreamReader(
                    Objects.requireNonNull(ChineseToSpellManagerImpl.class.getClassLoader().getResourceAsStream("userPinyin.txt")), StandardCharsets.UTF_8));
    try (PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(MultiPinyinConfig.multiPinyinPath),StandardCharsets.UTF_8))) {
        while ((line = br.readLine()) != null) {
            pw.println(line);
        }
    } catch (IOException e) {
        log.error("ChineseToSpellManager read file error.{}.", e.getMessage(), e);
    } finally {
        try {
            br.close();
        } catch (IOException e) {
            log.error("ChineseToSpellManager BufferedReader error.{}.", e.getMessage(), e);
        }
    }
}
    最后再次发版。再次发版读拼音!测试发现,还是找不到路径,根本就写到容器中的文件。 行,很行了。最后服了,不挂文件了,自己弄了一个枚举做字典,然后查枚举中拼音汉字,读吧..
//生僻字字典,可自行在枚举中添加
//目前数量少,量大可考虑添加缓存中
private static final Map initMap = ChinesePinEnum.readPinYinMap();

思考

    不管多简单的事,也要输出各种文档对比,不然会被质疑。要心平气和的面对每一次失败,发散思维方式,不要转牛角尖。docker挂在上,过于执着了,还好有个身边有人提醒换了方向。代码是最诚实的。

本地石墨写的地址:

https://shimo.im/docs/NJkbEgYPm2c75bqR/ 《中文转换拼音》,可复制链接后用石墨文档 App 或小程序打开

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/778200.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号