InvalidPathException: Malformed input or input contains unmappable characters 中文名文件 linux存储失败

1、报错信息

使用java.nio.file.Path规范并解析路径,生成文件到本地,部分文件名带中文。提供对外下载文件接口,用于下载这些文件,下载后的文件要显示中文名。本地(windows)开发调试都OK。通过docker容器部署到开发环境(linux集群)后,调用文件生成接口,后台报错,报错信息如下:

Unknown Error:Malformed input or input contains unmappable characters: ????????.xlsx
java.nio.file.InvalidPathException: 
Malformed input or input contains unmappable characters: ????????.xlsx

网上找的方案大都需要更新系统级的编码设置,一是比较麻烦,二是不确定会不会影响别人。

若你的需求是,在linux上查看时,文件名也需显示为中文,该文可以不看。

2、大致原因(不深究)

Path解析路径时,使用的getFileSystem().getPath(),获取当前系统并生成路径,查看getPath的说明,其中有一段,大意是在unix上,路径需要符合相应规范,否则会抛InvalidPathException。如果你的linux没有设置相应的语言,中文名就会引发上面的报错。所以可以考虑设置系统语言去解决(自行百度)

 3、不想进行系统级设置,临时方案:

使用base62对文件名进行encode后再存储,读取时再decode(不要使用base64,64中有/,会引发路径问题)。

base62可以使用hutool的Base62。hutool没有了解过的可以去百度一下,一个很好用的工具包


    public String encodeFileNameByBase62(String fileName) {
        if (StrUtil.isBlankIfStr(fileName)) {
            throw new ValidationException(ErrorCodeEnum.USER_ERROR_A0400, "待编码的文件名不能为空");
        }
        return fileName.contains(StrPool.DOT)
            ? Base62.encode(FileNameUtil.getPrefix(fileName)) + StrPool.DOT + FileNameUtil.extName(fileName)
            : Base62.encode(fileName);
    }

    public String decodeFileNameByBase62(String fileName) {
        if (StrUtil.isBlankIfStr(fileName)) {
            throw new ValidationException(ErrorCodeEnum.USER_ERROR_A0400, "待解析的文件名不能为空");
        }
        return fileName.contains(StrPool.DOT)
            ? Base62.decodeStr(FileNameUtil.getPrefix(fileName)) + StrPool.DOT + FileNameUtil.extName(fileName)
            : Base62.decodeStr(fileName);
    }

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值