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

背景

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

时间线

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

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

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

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

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

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

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

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

  1. 找到了运维,他是一次次的加路径改项目,最后找到了文件,也可以按照我的想法执行,但是发现致命的问题。
    1. 项目应用过多,若用docker挂载,需要在每个应用配置文件添加,日后还会私有化部署,这个很不友好。
    2. 现在公司还没有文件管理器,但凡要是加一个字在字典中,那就每个文件都加吧..
  2. 基于以上的问题,又想到可以在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);
        }
    }
}
  1. 最后再次发版。再次发版读拼音!测试发现,还是找不到路径,根本就写到容器中的文件。 行,很行了。
  2. 最后服了,不挂文件了,自己弄了一个枚举做字典,然后查枚举中拼音汉字,读吧..
//生僻字字典,可自行在枚举中添加
//目前数量少,量大可考虑添加缓存中
private static final Map<Character,String> initMap = ChinesePinEnum.readPinYinMap();

思考

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

本地石墨写的地址:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值