[ajug-members] Chaining OutputStreams

Jason Day jasonday at worldnet.att.net
Mon Apr 11 14:54:19 EDT 2005


On Mon, Apr 11, 2005 at 06:02:53AM -0400, Lee Grey wrote:
>             // transmit encrypted file
>             ServletOutputStream out = response.getOutputStream();
>             BufferedOutputStream buf = new BufferedOutputStream(out);
>             BufferedOutputStream bos = new BufferedOutputStream(buf);

This second BufferedOutputStream is unnecessary, no need to buffer the
data twice.

>             String filename = JFig.getInstance().getValue("file1",
> "filename");
>             try {
>                 // encrypt the file
>                 PdfReader reader = new PdfReader("WEB-INF/" + filename);
>                 String userPwd = StringUtil.createPDFPassword();
>                 PdfEncryptor.encrypt(reader, bos, true, userPwd, null,
> PdfWriter.AllowPrinting | PdfWriter.AllowDegradedPrinting);

Change "bos" to "buf".  This will send the output of the encryptor
directly to the servlet output stream.  You will need to set the
response headers first however.

>                 byte[] buffer = new byte[4*1024];
>                 int totalBytes = 0;
>                 int bytesRead;
>                 while(( bytesRead = bos.read(buffer, 0, buffer.length))
> != -1) {
>                     out.write(buffer, 0, bytesRead);
>                     totalBytes += bytesRead;
>                 }
>                 log.debug("wrote " + totalBytes + " bytes");
>                 out.flush();

The while loop is totally unnecessary, you've already written the data
to the output stream.

> The big problem comes in the while loop, where you have to have an
> InputStream to be able to call read().  Maybe that's not a problem, if you
> know what you're doing.  Can someone please show me how to send the output
> of the PdfEncryptor out to the servlet response stream?

I think something like this should work:

// transmit encrypted file                                                                                                                              
ServletOutputStream out = response.getOutputStream();                                                                                                   
BufferedOutputStream buf = new BufferedOutputStream(out);                                                                                               
String filename = JFig.getInstance().getValue("file1", "filename");                                                                                                                                                        
try {                                                                                                                                                   
    response.setContentType("application/pdf");                                                                                                         
    response.setHeader("Content-disposition", " attachment; filename=" + filename);
    int MAX_AGE_IN_SECONDS = 600;                                                                                                                       
    response.setHeader("Cache-Control", "max-age=" + MAX_AGE_IN_SECONDS);

    // encrypt the file                                                                                                                                 
    PdfReader reader = new PdfReader("WEB-INF/" + filename);                                                                                            
    String userPwd = StringUtil.createPDFPassword();                                                                                                    
    PdfEncryptor.encrypt(reader, buf, true, userPwd, null,
            PdfWriter.AllowPrinting | PdfWriter.AllowDegradedPrinting);
    buf.flush();                                                                                                                                        
    reader.close();
}
catch(Exception e) {                                                                                                                                  
    if( log.isErrorEnabled() ) {                                                                                                                        
        log.error("Failure during streaming of " + filename, e);                                                                                        
    }                                                                                                                                                   
}

Don't close the servlet output stream, that's the container's job.

HTH,
Jason
-- 
Jason Day                                       jasonday at
http://jasonday.home.att.net                    worldnet dot att dot net
 
"Of course I'm paranoid, everyone is trying to kill me."
    -- Weyoun-6, Star Trek: Deep Space 9



More information about the ajug-members mailing list