親ターゲットディレクトリ内の複数のxlsxファイルにデータを書き込むスタンドアロンのJavaプロセスを実行しています。完了すると、ターゲットディレクトリ全体が圧縮されてクラウドにアップロードされ、ダウンロードリンクがユーザーに提供されます。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コマンドの出力です。
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ロケールプロパティがスレーブで適切に設定されていませんでした。
スレーブの起動スクリプトに次の行を追加しました。
export LANG=en_IN.UTF-8
起動スクリプトにlocaleプロパティを明示的に追加すると、問題を解決できました。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加