简体   繁体   中英

FilesAlreadyExistsException when using Files.copy() on File.createTempFile()

I'm using JSF <h:inputFile> to upload images to the server.

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

I created a virtual host as /projectname/webapp/images . I can successfully create files into the folder.

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";
}

But all of them are empty and I get java.nio.file.FileAlreadyExistsException everytime.

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)

I use Logger to check the filesize, extension and streamsize, everything is fine.

How is this caused and how can I solve it?


Update : I added StandardCopyOption.REPLACE_EXISTING to Files.copy() and now it works, but it is still not solving the problem. I use createTempFile() to create unique, random filenames. Why would it say this file already exists?

The File#createTempFile() indeed immediately creates an empty file. This is to guarantee that the filename is already reserved and available for use, hereby removing the (very small) risk that another thread coincidentally concurrently generates the same filename at the same moment.

You should indeed be using StandardCopyOption.REPLACE_EXISTING in Files#copy() . This flag was not necessary in old FileOutputStream approach as it already defaults to overwriting the file.

I gather that you got the createTempFile() example from this answer ; it has in the meanwhile been updated to fix this oversight.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM