Java - 日文文件名乱码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java - 日文文件名乱码相关的知识,希望对你有一定的参考价值。

我正在运行一个独立的java进程,它将数据写入父目标目录中的多个xlsx文件,完成后,整个目标目录被压缩并上传到云,并向用户提供下载链接。 xlsx文件名和zip文件的名称是用户定义的,无法更改。

问题在于创建的xlsx文件的名称。如果用户选择的文件名是日语,例如

签署彩色纸目前CPN_No.2。xlsx

系统中创建的相应文件格式如下:

?????????? CPN_?2?.XLSX

相同的文件正在上传到云,用户看到乱码文件名。但是,zip文件的日文名称不会出现乱码,仅限日语。

以下是用于创建xlsx文件的代码示例:

String fileName = userGivenName + "_" + randomUUID + ".xlsx";
File file = new File(tmpParentDirectoryName, fileName);

FileOutputStream outputStream = new FileOutputStream(file);
workbook.write(outputStream);

在这种情况下,创建的xlsx文件的绝对路径如下:

/tmpDirectoryPath/??????????CPN_?2?_0c6b37ee-97c4-44d4-b80d-dfe5eafe0045.xlsx

就像上面一样,在同一个tmpDirectory中创建了多个xlsx文件

完成后,下面是创建zip文件并上传到云的代码示例:

File[] files = getFilesInFolder(tmpDirectory);
if (ArrayUtils.isEmpty(files)) {
        continue;
}

File zipFile = new File(targetDirectory, compressedFileName);
createZipFile(files, zipFile);
String url = uploadFile(compressedFileName, zipFile);

下面一段代码将数据写入zip文件:

public static void createZipFile(File[] files, File zipFile) {
    if (ArrayUtils.isEmpty(files)) {
        return;
    }

    byte[] buffer = new byte[1024];
    ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));

    try {
        for (File file : files) {
            FileInputStream fis = new FileInputStream(file);
            try {
                String fileName = URLDecoder.decode(file.getName(), "UTF-8");
                ZipEntry zipEntry = new ZipEntry(fileName);
                zos.putNextEntry(zipEntry);
                int length;
                while ((length = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, length);
                }
                zos.closeEntry();
            } finally {
                IOUtils.closeQuietly(fis);
            }
        }
    } finally {
        IOUtils.closeQuietly(zos);
    }
}

上传的zip文件具有正确的日文名称,但zip文件的zip条目使xlsx文件名出现乱码。

独立的java进程具有以下编码选项:

-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8

以下是locale命令的输出:

locale
LANG=en_IN.UTF-8
LC_CTYPE="en_IN.UTF-8"
LC_NUMERIC="en_IN.UTF-8"
LC_TIME="en_IN.UTF-8"
LC_COLLATE="en_IN.UTF-8"
LC_MONETARY="en_IN.UTF-8"
LC_MESSAGES="en_IN.UTF-8"
LC_PAPER="en_IN.UTF-8"
LC_NAME="en_IN.UTF-8"
LC_ADDRESS="en_IN.UTF-8"
LC_TELEPHONE="en_IN.UTF-8"
LC_MEASUREMENT="en_IN.UTF-8"
LC_IDENTIFICATION="en_IN.UTF-8"
LC_ALL=

有人可以指导我在这里做错了什么吗?我想要按照用户的指示上传相同的文件名。

答案

我终于能够破解这个了。问题在于执行java进程的mesos slave的系统属性。从属进程由一个使用启动脚本的mesos主调度程序启动。因此,未在从属设备上正确设置默认的java语言环境属性。

我将以下行添加到slave的启动脚本中:

export LANG=en_IN.UTF-8

在将语言环境属性显式添加到启动脚本后,能够解决该问题。

以上是关于Java - 日文文件名乱码的主要内容,如果未能解决你的问题,请参考以下文章

Superset导出CSV文件中文或日文乱码

输出日文CSV乱码问题

MMD日文乱码解决

日文系统下ultraedit安装后,菜单显示乱码问题。

日文符号“?”插入sql-server2005乱码问题

Visual Studio日文乱码解决方法