我正在使用JSF <h:inputFile>
将图像上传到服务器。
<h:form enctype="multipart/form-data">
<h:inputFile value="#{fileHandlerBean.file}"/>
<h:commandButton action="#{fileHandlerBean.uploadImage()}"/>
</h:form>
我创建了一个虚拟主机/projectname/webapp/images
。我可以成功地将文件创建到文件夹中。
private Part file;
public String uploadImage(){
InputStream is = null;
try {
String extension = FilenameUtils.getExtension(file.getSubmittedFileName());
File tempFile = File.createTempFile("picture-", "."+extension, new File("/projectname/webapp/images"));
Logger.getLogger("FILE SIZE").warning(String.valueOf(file.getSize()));
Logger.getLogger("FILE EXTENSION").warning(extension);
is = file.getInputStream();
Logger.getLogger("STREAM AVAILABLE SIZE").warning(String.valueOf(is.available()));
Files.copy(is, tempFile.toPath());
} catch (IOException ex) {
Logger.getLogger(FileHandlerBean.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if( is!= null){
try {
is.close();
} catch (IOException ex) {
Logger.getLogger(FileHandlerBean.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
return "success";
}
但是所有这些都是空的,我每次都会得到java.nio.file.FileAlreadyExistsException
。
java.nio.file.FileAlreadyExistsException: \projectname\webapp\images\picture-3433673623996534194.png
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:81)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
at java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:434)
at java.nio.file.Files.newOutputStream(Files.java:216)
at java.nio.file.Files.copy(Files.java:3016)
at com.toolmanagement.backingbeans.FileHandlerBean.uploadImage(FileHandlerBean.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
我使用Logger检查filesize,extension和streamsize,一切都很好。
这是如何引起的?如何解决?
更新:我已将StandardCopyOption.REPLACE_EXISTING
添加到Files.copy()
,现在可以正常运行,但仍未解决问题。我使用createTempFile()
创建唯一的随机文件名。为什么说这个文件已经存在?
答案 0 :(得分:8)
File#createTempFile()
确实会立即创建空文件。这是为了保证文件名已经保留并可供使用,从而消除了另一个线程在同一时刻同时生成相同文件名的(极小)风险。
您确实应该在StandardCopyOption.REPLACE_EXISTING
中使用Files#copy()
。旧FileOutputStream
方法中不需要此标志,因为它已默认覆盖文件。
我认为你从this answer获得createTempFile()
示例;它同时已经更新以解决这个疏忽。