Reading PDF with Defaultstreamedcontent. How to close it?

Asked

Viewed 862 times

4

I have a JSF page where I Gero a PDF and need to show it on the screen.

For that, I created a <p:media>

It is working, but the PDF file gets stuck (never closed) and over time it ends up knocking down the Tomcat by Many files open.

I tried to close the FileInputStream at the end of the method getStream(), but this causes error -> Error in streaming dynamic resource. Stream Close

Does anyone have any suggestions?

xhtml:

<p:dialog>
   <p:media value="#{reportMB.stream}" player="pdf" cache="disable"/>
</p:dialog>

Managedbean (@Sessionscope):

public StreamedContent getStream(){
    StreamedContent content=null;
    FileInputStream fis=null;
    try{
        File pdf = new File("/meudiretorio/meuarquivo.pdf");
        fis = new FileInputStream(pdf);
        content=new DefaultStreamedContent(fis,"application/pdf","nomequalquer");
    }catch(IOException e){
    }
    return content;
}

2 answers

2

For what I found in this matter of Soen and see in the implementation of the class DefaultStreamedContent, Stream is never closed through the method close.

You also cannot close it within the method as it will still be read and transmitted to the user.

To solution pointed out by the same author of the aforementioned question was copying the bytes of the file to a stream in memory, because in this way the StreamedContent does not get linked to the file on the disk. The problem with this approach is that the entire file will be read in memory.

Another option, that would not have problems related to memory, however seems to me a gambiarra, would save a reference to the FileInputStream as an attribute of the request or session (depending on how many requests Primefaces makes to retrieve the PDF) and then implement a Listener to execute the close at the end of the request, where Primefaces would have already sent the data to the user.

A third alternative would be to create a new InputStream as a wrapper to the FileInputStream so that it would detect the end of the file and then incovasse the close in the file stream automatically.

  • 1

    I just tested a similar approach to the new author’s solution Bytearrayinputstream(Fileutils.readFileToByteArray(pdf)) but tmb think I’ll have a problem with memory. I will try to implement a wrapper as you suggested. Let’s see what comes ;)

0

StreamedContent.getStream is closed by the classes:

  • FileDownloadActionListener
  • PrimeResourceHandler

Then at the end of the request the Primefaces itself is in charge of closing the InputStream.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.