2014-06-21 47 views
45

任何人都可以告訴我什麼是將多部分文件(org.springframework.web.multipart.MultipartFile)轉換爲File(java.io.File)的最佳方式?如何將多部分文件轉換爲文件?

在我的Spring MVC的Web項目我得到上傳的文件多部分file.I必須將其轉換爲一個文件(IO),還有前我可以調用這個圖像存儲服務(Cloudinary)。他們只需要鍵入(文件)。

我做了這麼多搜索,但失敗了。如果有人知道一個好的標準方式,請讓我知道? 日Thnx

+3

是否有某些東西阻止您使用'MultipartFile.transferTo()'方法? – fajarkoe

回答

119

您可以通過使用getBytes方法得到multipartFile的內容,你可以通過使用FileOutputStream類創建File類的一個實例。

public File convert(MultipartFile file) 
{  
    File convFile = new File(file.getOriginalFilename()); 
    convFile.createNewFile(); 
    FileOutputStream fos = new FileOutputStream(convFile); 
    fos.write(file.getBytes()); 
    fos.close(); 
    return convFile; 
} 

您還可以使用transferTo method

public File multipartToFile(MultipartFile multipart) throws IllegalStateException, IOException 
{ 
    File convFile = new File(multipart.getOriginalFilename()); 
    multipart.transferTo(convFile); 
    return convFile; 
} 
+2

我用transferTo函數,但我覺得有一個問題。就像它保存臨時文件以驅動本地機器一樣。 – Ronnie

+0

@羅尼我有同樣的問題。你有沒有發現任何解決方法? –

+0

org.apache.commons.io.FileUtils.deleteQuietly(convFile.getParentFile()); ,這應該刪除臨時文件@Ronnie – kavinder

2

您還可以使用Apache Commons IO庫和FileUtils class。如果你正在使用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()); 
+0

'FileUtils.touch()'在這裏既沒有意義也沒有浪費。您現在需要'新的FileOutputStream()'(通過操作系統)來刪除創建的文件*和*創建一個新文件。 – EJP

+0

感謝您的評論。我檢查了FileUtils.writeByteArrayToFile方法的來源。我認爲這種方法不會在文件存在的情況下重新創建文件(版本2.4)。 multipartFile對象包含我們想要存儲在文件系統某處的上傳文件的字節。我的目的是將這些字節存儲到首選位置。我保留FileUtils.touch方法的唯一原因是要明確這是一個新文件。如果FileUtils.writeByteArrayToFile不存在,FileUtils.writeByteArrayToFile將創建文件(和完整路徑),因此FileUtils.touch不是必需的。 –

2

您可以通過鑄造如果類接口MultipartFile的是CommonsMultipartFile在春天訪問臨時文件。

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; 
    } 
+1

'createNewFIle()'在這裏既毫無意義又浪費。您現在需要'新的FileOutputStream()'(通過操作系統)來刪除創建的文件*和*創建一個新文件。 – EJP

+0

@EJP是的,這是毫無意義的,現在我解決了編輯時犯的這個錯誤。但createNewFIle()不是浪費,因爲如果CommonsMultipartFile小於10240字節,則不會創建文件系統中的文件。因此,應該在FS中創建具有任何唯一名稱的新文件(我使用DiskFileItem的名稱)。 – Alex78191

+0

@ Alex78191你的意思是隱式保存在磁盤上的小文件(默認<10240字節)。無論如何增加限制 –

8

雖然接受的答案是正確的,但如果你只是想上傳圖片到cloudinary,有一個更好的辦法:

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

哪裏multipartFile是您org.springframework.web.multipart .MultipartFile

1

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> 
+0

'maxInMemorySize'與文件上傳大小的限制無關。文件上傳大小由'maxUploadSize'屬性設置。 – Alex78191

+0

爲了擺脫小於10240字節的文件,'maxInMemorySize' prop可以設置爲'0'。 – Alex78191

+0

@ Alex78191我改變了這一點,它爲我工作。我已經使用你的代碼來轉換文件。所以我改變了applicationcontext.xml中的屬性來擺脫內存限制。它的作品! –

0

小幅盤整於@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(...)

相關問題