如何将多部分文件转换为文件?

IT小君   2021-10-20T14:00:43

谁能告诉我将多部分文件 (org.springframework.web.multipart.MultipartFile) 转换为 File (java.io.File) 的最佳方法是什么?

在我的 spring mvc web 项目中,我将上传的文件作为多部分文件。我必须将其转换为 File(io) ,因此我可以调用此图像存储服务(Cloudinary)。它们只采用类型(文件)。

我做了很多搜索但都失败了。如果有人知道一个好的标准方法,请告诉我?谢谢

评论(10)
IT小君

您可以MultipartFile使用getBytes方法获取 a 的内容,并且可以使用以下方法写入文件Files.newOutputStream()

public void write(MultipartFile file, Path dir) {
    Path filepath = Paths.get(dir.toString(), file.getOriginalFilename());

    try (OutputStream os = Files.newOutputStream(filepath)) {
        os.write(file.getBytes());
    }
}

您还可以使用transferTo 方法

public void multipartFileToFile(
    MultipartFile multipart, 
    Path dir
) throws IOException {
    Path filepath = Paths.get(dir.toString(), multipart.getOriginalFilename());
    multipart.transferTo(filepath);
}
2021-10-20T14:00:43   回复
IT小君

对@PetrosTsialiamanis 帖子的小更正, new File( multipart.getOriginalFilename())这将在服务器位置创建文件,有时您将在该位置面临用户的写权限问题,并不总是可以为执行操作的每个用户授予写权限。 System.getProperty("java.io.tmpdir")将创建临时目录,您的文件将在其中正确创建。这样您就可以创建临时文件夹,在其中创建文件,稍后您可以删除文件或临时文件夹。

public  static File multipartToFile(MultipartFile multipart, String fileName) throws IllegalStateException, IOException {
    File convFile = new File(System.getProperty("java.io.tmpdir")+"/"+fileName);
    multipart.transferTo(convFile);
    return convFile;
}

将此方法放入您的通用实用程序中并使用它,例如。 Utility.multipartToFile(...)

2021-10-20T14:00:43   回复
IT小君

虽然接受的答案是正确的,但如果您只是想将图像上传到 cloudinary,则有更好的方法:

Map upload = cloudinary.uploader().upload(multipartFile.getBytes(), ObjectUtils.emptyMap());

其中 multipartFile 是您的org.springframework.web.multipart.MultipartFile

2021-10-20T14:00:43   回复
IT小君

MultipartFile.transferTo(File) 很好,但毕竟不要忘记清理临时文件。

// ask JVM to ask operating system to create temp file
File tempFile = File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_POSTFIX);

// ask JVM to delete it upon JVM exit if you forgot / can't delete due exception
tempFile.deleteOnExit();

// transfer MultipartFile to File
multipartFile.transferTo(tempFile);

// do business logic here
result = businessLogic(tempFile);

// tidy up
tempFile.delete();

在下面查看 Razzlero 关于在 JVM 退出时执行的 File.deleteOnExit() 的评论(这可能非常罕见)详细信息。

2021-10-20T14:00:44   回复
IT小君
  private File convertMultiPartToFile(MultipartFile file ) throws IOException
    {
        File convFile = new File( file.getOriginalFilename() );
        FileOutputStream fos = new FileOutputStream( convFile );
        fos.write( file.getBytes() );
        fos.close();
        return convFile;
    }
2021-10-20T14:00:44   回复
IT小君

您还可以使用Apache Commons IO库和FileUtils 类如果您使用的是 maven,则可以使用上述依赖项加载它。

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

MultipartFile 保存到磁盘的源。

File file = new File(directory, filename);

// Create the file using the touch method of the FileUtils class.
// FileUtils.touch(file);

// Write bytes from the multipart file to disk.
FileUtils.writeByteArrayToFile(file, multipartFile.getBytes());
2021-10-20T14:00:44   回复
IT小君

如果接口的类MultipartFileCommonsMultipartFile.

public File getTempFile(MultipartFile multipartFile)
{
    CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) multipartFile;
    FileItem fileItem = commonsMultipartFile.getFileItem();
    DiskFileItem diskFileItem = (DiskFileItem) fileItem;
    String absPath = diskFileItem.getStoreLocation().getAbsolutePath();
    File file = new File(absPath);

    //trick to implicitly save on disk small files (<10240 bytes by default)
    if (!file.exists()) {
        file.createNewFile();
        multipartFile.transferTo(file);
    }

    return file;
}

要摆脱文件小于 10240 字节的技巧,maxInMemorySize可以在@Configuration @EnableWebMvc中将属性设置为 0 之后,所有上传的文件都将存储在磁盘上。

@Bean(name = "multipartResolver")
    public CommonsMultipartResolver createMultipartResolver() {
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        resolver.setDefaultEncoding("utf-8");
        resolver.setMaxInMemorySize(0);
        return resolver;
    }
2021-10-20T14:00:44   回复
IT小君

使用 Apache Commons 的单行回答。

FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);

2021-10-20T14:00:44   回复
IT小君

Alex78191 的回答对我有用。

public File getTempFile(MultipartFile multipartFile)
{

CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) multipartFile;
FileItem fileItem = commonsMultipartFile.getFileItem();
DiskFileItem diskFileItem = (DiskFileItem) fileItem;
String absPath = diskFileItem.getStoreLocation().getAbsolutePath();
File file = new File(absPath);

//trick to implicitly save on disk small files (<10240 bytes by default)

if (!file.exists()) {
    file.createNewFile();
    multipartFile.transferTo(file);
}

return file;
}

要上传大于 10240 字节的文件,请将 multipartResolver 中的 maxInMemorySize 更改为 1MB。

<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size t 20MB -->
<property name="maxUploadSize" value="20971520" />
<!-- max size of file in memory (in bytes) -->
<property name="maxInMemorySize" value="1048576" />
<!-- 1MB --> </bean>
2021-10-20T14:00:44   回复
IT小君

如果您不想使用 MultipartFile.transferTo()。你可以这样写文件

    val dir = File(filePackagePath)
    if (!dir.exists()) dir.mkdirs()

    val file = File("$filePackagePath${multipartFile.originalFilename}").apply {
        createNewFile()
    }

    FileOutputStream(file).use {
        it.write(multipartFile.bytes)
    }
2021-10-20T14:00:44   回复