How to fix an error `Java heap space` when downloading large files (GB) using Liferay

后端 未结 3 917
死守一世寂寞
死守一世寂寞 2021-01-26 16:03

I am using this code to download an existing file from the server on Liferay (6.2) into a local pc:

`

    File file = getFile(diskImage.getImageType(), d         


        
相关标签:
3条回答
  • 2021-01-26 16:25

    First of all: I'm assuming you're doing this in a render method - and this is just plain wrong. Sooner or later this will break, because you don't have control over the output stream: It might already be committed and transmit data to the browser when your portlet starts to render. In render you always must generate a portlet's HTML code.

    Instead, you should go to the resource serving phase of a portlet. With the ResourceRequest and ResourceResponse, you have a very similar support for setting mimetypes as with HttpServletResponse.

    And for exactly that reason, ServletResponseUtil is indeed the wrong place to look for. If you use anything from Liferay, you should look for PortletResponseUtil. There are various sendFile methods that accept a byte[], others accept a stream or a file. I'd recommend to try these, if they still fail, look at the implementation you are ending up with. In the worst case, just don't use any of the Util methods. Copying content from one stream to another is not too bad. (Actually, you give no clue about the static type of your variable input in the question: If that's a byte[], there's your solution)

    You might want to file an issue with Liferay, if indeed the pure stream-transfer does read the whole file into memory, but your quickfix (in case this is indeed a bug) would be to copy the data yourself.

    0 讨论(0)
  • 2021-01-26 16:34

    Thanks for thoughts, finally I used PortletResponseUtil.sendFile(...); method and changed actionURL to responseURL in .jsp file. So that I implemented serveResource()with above mentioned method. It seems that everything is working fine.

    0 讨论(0)
  • 2021-01-26 16:44

    ServletResponseUtil.sendFile(httpReq, httpResp, file.getName(), input, "application/octet-stream"); what's this?

    Don't read a file once time.Use a buffer.

    response.reset();
    response.setContentType("application/x-download");
    response.addHeader("Content-Disposition","attachment;filename="+new String(filename.getBytes(),"utf-8"));
    response.addHeader("Content-Length",""+file.length());
    OutputStream toClient=new BufferedOutputStream(response.getOutputStream());
    response.setContentType("application/octet-stream");
    byte[] buffer=new byte[1024*1024*4];
    int i=-1;
    while((i=fis.read(buffer))!=-1){
      toClient.write(buffer,0,i);
    }
    fis.close();
    toClient.flush();
    toClient.close();
    
    0 讨论(0)
提交回复
热议问题