Java - 日本文件名乱码
Java - Japanese filenames garbled
我是 运行 一个独立的 java 进程,它将数据写入父目标目录中的多个 xlsx 文件,完成后,整个目标目录被压缩并上传到云端,并下载 link 提供给用户。 xlsx 文件名和 zip 文件名是用户定义的,无法更改。
问题出在创建的 xlsx 文件的名称上。如果用户选择的文件名是日文,比如
サイン色紙プレゼントCPN_第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
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 从站的系统属性上。
从站上的进程由 mesos 主调度程序使用启动脚本启动。由于这个原因,默认的 java 语言环境属性没有在从服务器上正确设置。
我在 slave 的 start-up 脚本中添加了以下行:
export LANG=en_IN.UTF-8
将语言环境 属性 显式添加到 start-up 脚本后,问题得以解决。
我是 运行 一个独立的 java 进程,它将数据写入父目标目录中的多个 xlsx 文件,完成后,整个目标目录被压缩并上传到云端,并下载 link 提供给用户。 xlsx 文件名和 zip 文件名是用户定义的,无法更改。
问题出在创建的 xlsx 文件的名称上。如果用户选择的文件名是日文,比如
サイン色紙プレゼントCPN_第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
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 从站的系统属性上。 从站上的进程由 mesos 主调度程序使用启动脚本启动。由于这个原因,默认的 java 语言环境属性没有在从服务器上正确设置。
我在 slave 的 start-up 脚本中添加了以下行:
export LANG=en_IN.UTF-8
将语言环境 属性 显式添加到 start-up 脚本后,问题得以解决。