我正在运行一个独立的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
在将语言环境属性显式添加到启动脚本后,能够解决该问题。