Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SpringMVC:下载大文件,OutOfMemoryException_Java_Spring Mvc_Download - Fatal编程技术网

Java SpringMVC:下载大文件,OutOfMemoryException

Java SpringMVC:下载大文件,OutOfMemoryException,java,spring-mvc,download,Java,Spring Mvc,Download,如何通过spring controller提供大文件供下载?我关注了一些关于类似主题的讨论: 但是这些解决方案对于300mb到600mb的大文件来说是失败的。 在最后一行中,我正在退出MemoryException: @RequestMapping(value = "/file/{dummyparam}.pdf", method = RequestMethod.GET, produces=MediaType.APPLICATION_OCTET_STREAM_VALUE) public @Res

如何通过spring controller提供大文件供下载?我关注了一些关于类似主题的讨论:

但是这些解决方案对于300mb到600mb的大文件来说是失败的。 在最后一行中,我正在退出MemoryException:

@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


简单的方法是将文件作为静态内容链接到webserver目录中,但我们希望在Spring应用程序中尝试这样做。

这是因为您要将整个文件读取到内存中,请使用缓冲读写

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

对于Spring,需要在ResponseEntity中使用InputStreamResource

演示代码:

        MediaType mediaType = MediaTypeUtils.getMediaTypeForFileName(this.servletContext, fileName);
        System.out.println("fileName: " + fileName);
        System.out.println("mediaType: " + mediaType);

        File file = new File(DIRECTORY + "/" + fileName);
        InputStreamResource resource = new InputStreamResource(new FileInputStream(file));

        return ResponseEntity.ok()
                // Content-Disposition
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + file.getName())
                // Content-Type
                .contentType(mediaType)
                // Contet-Length
                .contentLength(file.length()) //
                .body(resource);
    }

Ref Link:

p在上述实现中下载的字节大小应该是多少?请改用,
IOUtils.copyragle(inputStream,response.getOutputStream())其中缓冲区大小默认为\u buffer\u size。根据jar版本的不同,大小可能从4KB到8KB不等。