File.createTempFile()上使用Files.copy()时FilesAlreadyExistsException

h2c*_*h2c 5 java jsf file

我正在使用JSF <h:inputFile>将图像上传到服务器.

<h:form enctype="multipart/form-data">
    <h:inputFile value="#{fileHandlerBean.file}"/>
    <h:commandButton action="#{fileHandlerBean.uploadImage()}"/>
</h:form>
Run Code Online (Sandbox Code Playgroud)

我创建了一个虚拟主机/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";
}
Run Code Online (Sandbox Code Playgroud)

但是所有这些都是空的,我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)
Run Code Online (Sandbox Code Playgroud)

我使用Logger来检查filesize,extension和streamsize,一切都很好.

这是怎么造成的,我该如何解决?


更新:我添加StandardCopyOption.REPLACE_EXISTINGFiles.copy()现在它的工作原理,但它仍然无法解决问题.我createTempFile()用来创建独特的随机文件名.为什么会说这个文件已经存在?

Bal*_*usC 9

File#createTempFile()的确马上创建一个文件.这是为了保证文件名已经保留并可供使用,从而消除了另一个线程同时在同一时刻同时生成相同文件名的(极小)风险.

事实上,你应该使用StandardCopyOption.REPLACE_EXISTINGFiles#copy().旧FileOutputStream方法中不需要此标志,因为它已默认覆盖文件.

我知道你createTempFile()这个答案中得到了榜样; 同时它已经更新以解决这个疏忽.

  • 每当@BalusC回答任何问题时,我们都可以盲目跟随它. (2认同)