【发布时间】:2016-04-17 12:01:15
【问题描述】:
我有一个 servlet,它使用 Apache Commons fileupload 将上传的文件写入磁盘。总的来说,这一切都很好。
它使用 Tomcat 在 Windows 和 Linux 服务器上运行。在 Windows 上,它可以正确处理具有非 ASCII 文件名的文件,并正确保存文件。
在 Linux (CentOS 6) 上,但文件名在包含非 ASCII 字符时无法正确保存。
如果尝试过三种不同版本的文件写入方式。在 Windows 中一切正常,在 Linux 中没有,但它们会产生不同的结果。
版本 1:
String fileName = URLDecoder.decode(encFilename, "UTF-8");
String filePath = uploadFolder + File.separator + fileName;
File uploadedFile = new File(filePath);
item.write(uploadedFile);
版本 2:
String fileName = URLDecoder.decode(encFilename, "UTF-8");
String filePath = uploadFolder + File.separator + fileName;
File uploadedFile = new File(filePath);
InputStream input = item.getInputStream();
try {
Files.copy(input, uploadedFile.toPath());
} catch (Exception e) {
log.error("Error writing file to disk: " + e.getMessage());
} finally {
input.close();
}
上传一个名为:Это тестовый файл.txt 的文件我在 Linux 上得到以下结果:
版本 1:文件名为:??? ???????? ????.txt
第 2 版:Error writing file to disk: Malformed input or input contains unmappable characters: /tmp/Это тестовый файл.txt
在装有 Tomcat 7 和 Java 7 的 Windows 机器上,文件名正确写入为 Это тестовый файл.txt
第三个版本使用来自this post 的方法并且不使用FileUpload。结果与版本 2 产生的结果相同。
版本 3:
Part filePart = request.getPart("file");
String fileName = "";
for (String cd : filePart.getHeader("content-disposition").split(";")) {
if (cd.trim().startsWith("filename")) {
fileName = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
fileName = fileName.substring(fileName.lastIndexOf('/') + 1).substring(fileName.lastIndexOf('\\') + 1); // MSIE fix.
}
}
String filePath = uploadFolder + File.separator + fileName;
File uploadedFile = new File(filePath);
InputStream input = filePart.getInputStream();
try {
Files.copy(input, uploadedFile.toPath());
} catch (Exception e) {
log.error("Error writing file to disk: " + e.getMessage());
} finally {
input.close();
}
Tomcat 使用 -Dfile.encoding=UTF-8 运行,locale 显示 LANG=en_US.UTF-8
touch "Это тестовый файл.txt" 生成一个具有该名称的文件。
文件内容始终正确写入。 (当然除了根本没有写入文件)。
我错过了什么或做错了什么?
【问题讨论】:
-
为什么要通过
File?直接用Path就行了 -
尝试调试每个版本,看看
fileName在所有三种情况下是什么
标签: java servlets file-upload character-encoding