8

spring controller を介してダウンロードする大きなファイルを提供するにはどうすればよいですか? 私は同様のトピックに関するいくつかの議論に従いました:

スプリング コントローラーからのファイルのダウンロード

しかし、これらのソリューションは、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 MB です。同時ダウンロードの最大数は 10 と推定されます。

簡単な方法は、ファイルを webserver ディレクトリの静的コンテンツとしてリンクすることですが、Spring アプリ内でそれを試してみたいと思います。

4

2 に答える 2

22

これは、ファイル全体をメモリに読み込んでいるためです。代わりに、バッファリングされた読み書きを使用してください。

@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(); 
}
于 2013-04-04T00:33:28.710 に答える