Neil
Neil

Reputation: 89

java.nio.file.NoSuchFileException When File.transferTo() is called

I've recently inherited a Java API and am having trouble with file uploads. Unfortunately, Java isn't a language I have much experience in so I'm a bit stumped by this.

The MultiPartFile is being received ok, and I can find the file in the temp directory, but when I try to use File.transferTo() to create the final file I just get the below error;

java.nio.file.NoSuchFileException: C:\Users\myUser\AppData\Local\Temp\undertow3706399294849267898upload -> S:\Dev\PolicyData\Temp.xlsx

As I mentioned the temp undertow file exists, and the directory on the S drive also exist, (but there's no Temp.xlsx as my understanding is this should be created by transferTo()). Any solutions I've found to this problem so far are resolved using absolute file paths.

This is a simplified version of the code but the error remains the same.

SpringBoot framework is "1.5.3.RELEASE", running Java 1.8.0_131

    ResponseEntity handleFileUpload(@RequestPart(name = "file") MultipartFile file, @PathVariable Long stageFileTypeId) {
    if (!file.isEmpty()) {
        try {
            String filePath = "S:\\Dev\\PolicyData\\Temp.xlsx";
            log.info("Upload Path = {}", filePath);

            File dest = new File(filePath);
            file.transferTo(dest);

            return ResponseUtil.wrapOrNotFound(Optional.ofNullable(filePath));
        }
        catch (Exception ex) {
            log.error("An error has occurred uploading the file", ex);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    else {
        log.error("An error has occurred, no file was received");
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    }
}

If you need any more information please let me know.

Thanks, Neil

Upvotes: 1

Views: 3881

Answers (1)

areus
areus

Reputation: 2947

The API for MultipartFile is a bit tricky. The transferTo(File) method javadoc states that (bold are mine):

This may either move the file in the filesystem, copy the file in the filesystem, or save memory-held contents to the destination file. If the destination file already exists, it will be deleted first.

If the target file has been moved in the filesystem, this operation cannot be invoked again afterwards. Therefore, call this method just once in order to work with any storage mechanism.

It seems that the Undertow implementantion already called it to move the in-memory uploaded file to "C:\Users\myUser\AppData\Loca\Temp\undertow3706399294849267898upload" so another transferTo is failing.

I came across the same problem using javax.servlet.http.Part in a Wildfly containter with Undertow.

If you are using Spring framework >= 5.1, you could try the Multipart.transferTo(Path) method, using dest.toPath()

Or you can copy from the inputStream, with something like this:

try (InputStream is = multipartFile.getInputStream()) {
    Files.copy(is, dest.toPath());
}

Upvotes: 2

Related Questions