Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this quick tutorial, we’ll learn various ways of converting a Spring MultipartFile to a File and vice versa.

2. Converting MultipartFile to File

The MultipartFile class provides methods like getBytes(), getInputStream(), and transferTo() to convert MultipartFile to File.

2.1. Using MultipartFile#getBytes

MultipartFile has a getBytes() method that returns a byte array of the file’s contents. We can use this method to write the bytes to a file:

MultipartFile multipartFile = new MockMultipartFile("sourceFile.tmp", "Hello World".getBytes());

File file = new File("src/main/resources/targetFile.tmp");

try (OutputStream os = new FileOutputStream(file)) {
    os.write(multipartFile.getBytes());
}

assertThat(FileUtils.readFileToString(new File("src/main/resources/targetFile.tmp"), "UTF-8"))
  .isEqualTo("Hello World");

The getBytes() method is useful for instances where we want to perform additional operations on the file before writing to disk, like computing a file hash.

2.2. Using MultipartFile#getInputStream

Next, let’s look at MultipartFile‘s getInputStream() method:

MultipartFile multipartFile = new MockMultipartFile("sourceFile.tmp", "Hello World".getBytes());

InputStream initialStream = multipartFile.getInputStream();
byte[] buffer = new byte[initialStream.available()];
initialStream.read(buffer);

File targetFile = new File("src/main/resources/targetFile.tmp");

try (OutputStream outStream = new FileOutputStream(targetFile)) {
    outStream.write(buffer);
}

assertThat(FileUtils.readFileToString(new File("src/main/resources/targetFile.tmp"), "UTF-8"))
  .isEqualTo("Hello World");

Here we’re using the getInputStream() method to get the InputStream, read the bytes from the InputStream, and store them in the byte[] buffer. Then we create a File and OutputStream to write the buffer contents.

The getInputStream() approach is useful in instances where we need to wrap the InputStream in another InputStream, say for example a GZipInputStream if the uploaded file was gzipped.

2.3. Using MultipartFile#transferTo

Finally, let’s look at MultipartFile‘s transferTo() method:

MultipartFile multipartFile = new MockMultipartFile("sourceFile.tmp", "Hello World".getBytes());

File file = new File("src/main/resources/targetFile.tmp");

multipartFile.transferTo(file);

assertThat(FileUtils.readFileToString(new File("src/main/resources/targetFile.tmp"), "UTF-8"))
  .isEqualTo("Hello World");

Using the transferTo() method, we simply have to create the File that we want to write the bytes to, then pass that file to the transferTo() method.

The transferTo() method is useful when the MultipartFile only needs to be written to a File.

3. Converting File to MultipartFile

We can convert a File object to MultipartFile using the MockMultipartFile class and the Apache Commons libraries.

3.1. Using MockMultipartFile Class

The Spring framework provides the MockMultipartFile class to convert between File object and MultipartFile object. However, this class is intended to be used only in test scopes.

Let’s see an example code that uses MockMultipartFile to convert File to MultipartFile:

@Test
void givenFile_whenCreateMultipartFile_thenContentMatch() throws IOException {
    File file = new File("src/main/resources/targetFile.tmp");
    byte[] fileBytes = Files.readAllBytes(file.toPath());
    MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", fileBytes);
    String fileContent = new String(multipartFile.getBytes());
    assertEquals("Hello World", fileContent);
    assertEquals("targetFile.tmp", multipartFile.getOriginalFilename());
}

In the code above, we create a File object and pass it to an instance of MockMultipartFile. MockMultipartFile accepts the file name, file type, and the file bytes as arguments.

Finally, we assert the MultipartFile content is equal to the expected content.

Notably, this method is best used in test code and not in a production environment.

3.2. Using Apache Common Libraries (Spring Boot 2)

Note that Apache Common Libraries are no longer supported in Spring Boot 3.

If you are using Spring Boot 2, you can use the Apache Commons IO and Apache Commons FileUpload libraries that provide APIs to convert File to MultipartFile.

To begin with, let’s add the Apache Commons IO and Apache Commons FileUpload dependencies to the pom.xml:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.15.1</version>
</dependency>
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.5</version>
</dependency>

Next, let’s see an example code that uses the two libraries to convert File to MultipartFile:

@Test
void givenFile_whenCreateMultipartFileUsingCommonsMultipart_thenContentMatch() throws IOException {
    File file = new File("src/main/resources/targetFile.tmp");
    FileItem fileItem = new DiskFileItem("file", Files.probeContentType(file.toPath()), 
      false, file.getName(), (int) file.length(), file.getParentFile());
    InputStream input = new FileInputStream(file);
    OutputStream outputStream = fileItem.getOutputStream();
    IOUtils.copy(input, outputStream);
    MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
    String fileContent = new String(multipartFile.getBytes());
    assertEquals("Hello World", fileContent);
    assertEquals("targetFile.tmp", multipartFile.getOriginalFilename());
}

First, we create a File object and pass some of its methods to the DiskFileItem object. Next, we create an instance of FileInputStream which accepts the File object as an argument.

Furthermore, we invoke the getOutputStream() method on the DiskFileItem object and use the copy() from the Apache Commons IO library to copy from InputStream to OutputStream. The copy() method saves the file content to the DiskFileItem object.

Finally, we create the CommonsMultipartFile object which accepts the DiskFileItem and completes the File to MultipartFile conversion.

Notably, this is the best approach for converting File to MultipartFile in production applications.

4. Conclusion

In this article, we explored ways of converting between MultipartFile and File in Spring.

As usual, all code examples can be found over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.