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); }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)