Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
287 views
in Technique[技术] by (71.8m points)

java - Spring MVC : large files for download, OutOfMemoryException

How to provide large files for download through spring controller ? I followed few discussions on similar topic :

Downloading a file from spring controllers

but those solutions fails for large files ~ 300mb - 600mb. I am getting OutOfMemoryException on the last line :

@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);

My (naive) assumption was that IOUtils will handle even large files but this is not obviously happening. Is there any way how to split file into chunks as download is in progress ? Files are usually around 300 - 600mb large. Max number of concurrent downloads is estimated to 10.

Easy way would be to link files as static content in the webserver directory but we would like to try do it in within our Spring app.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It is because you are reading the entire file into memory, use a buffered read and write instead.

@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(); 
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...