2013-04-04 3 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 - 600 мб. Максимальное количество одновременных загрузок оценивается в 10.

Простым способом было бы связать файлы как статические материалы в каталоге веб-сервера, но мы хотели бы попробовать сделать это в нашем приложении 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(); 
} 
Смежные вопросы