2013-04-04 80 views
4

如何通過彈簧控制器提供大文件下載?我跟着類似的話題討論數:Spring MVC:大文件下載,OutOfMemoryException

Downloading a file from spring controllers

,但這些解決方案未能對大文件〜300MB - 600MB。 我收到OutOfMemoryException異常的最後一行:

@RequestMapping(value = "/file/{dummyparam}.pdf", method = RequestMethod.GET, produces=MediaType.APPLICATION_OCTET_STREAM_VALUE) 
public @ResponseBody byte[] getFile(@PathVariable("dummyparam") String dummyparam, HttpServletResponse response) { 
. 
.  
InputStream is = new FileInputStream(resultFile); 

response.setHeader("Content-Disposition", "attachment; filename=\"dummyname " + dummyparam + ".pdf\""); 
. 
.   
return IOUtils.toByteArray(is); 

我的(幼稚)的假設是,IOUtils將處理即使是大文件,但是這不是明顯的發生。有什麼辦法如何下載正在進行的文件分割成塊?文件通常大約300-600mb大。最大併發下載量估計爲10.

簡單的方法是將文件鏈接爲web服務器目錄中的靜態內容,但我們希望嘗試在我們的Spring應用程序中執行此操作。

回答

10

這是因爲您正在將整個文件讀入內存,而是使用緩衝讀寫。

@RequestMapping(value = "/file/{dummyparam}.pdf", method = RequestMethod.GET, produces=MediaType.APPLICATION_OCTET_STREAM_VALUE) 
public void getFile(@PathVariable("dummyparam") String dummyparam, HttpServletResponse response) { 


    InputStream is = new FileInputStream(resultFile); 

    response.setHeader("Content-Disposition", "attachment; filename=\"dummyname " + dummyparam + ".pdf\""); 


    int read=0; 
    byte[] bytes = new byte[BYTES_DOWNLOAD]; 
    OutputStream os = response.getOutputStream(); 

    while((read = is.read(bytes))!= -1){ 
     os.write(bytes, 0, read); 
    } 
    os.flush(); 
    os.close(); 
}