Link to home
Start Free TrialLog in
Avatar of blackfrancis75
blackfrancis75

asked on

Tomcat - PDF Servlet output corrupted


Hello,
I have written up a Tomcat servlet to display some PDF files in a browser.  The files are not in a sub-directory of the web application, so in order to render them in the browser I am reading a file byte-wise into a ByteArrayOutputStream like this:

ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedReader in = new BufferedReader(new FileReader(file));
int b = 0;
while ((b = in.read()) > -1)
{
    out.write( b );
}      

Then, I am outputting the data to the servlet response stream like this:

response.getOutputStream().write( out.getByteArray() );
response.getOutputStream().flush();


The problem I have is that the data that is written to the ServletOutputStream is corrupted - every so often a byte is wrong in the output (although for the most part they are ok).
I did a bit of looking around and found this in the API doc for java.io.OutputStream.:

"public abstract void write(int b) throws IOException
Writes the specified byte to this output stream. The general contract for write is that one byte is written to the output stream.
The byte to be written is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored.
Subclasses of OutputStream must provide an implementation for this method. "

I think this is the cause of my data corruption - can someone tell me how to output the data without this happening?
ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
(Reader is designed for text and interprets bytes - you need something that reproduces them without interpretation)
Avatar of blackfrancis75
blackfrancis75

ASKER

Sorry, could you elaborate?
I tried:
BufferedInputStream in = new BufferedInputStream( file );

but that's not right
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
should be more like:

InputStream in = new new FileInputStream(file));
OutputStream out = response.getOutputStream();
int b = 0;
byte[] buf = new byte[256];
while ((b = in.read(buf)) > -1)
{
    out.write( buf, 0, b );
}      
You also need to write to the ServletOutputStream, not its Writer, for the same reason
The BufferedReader will attempt to decode the data read as test which would cvause the corruption
You can also avoid storing the entire file in memory by writing directly to response
thanks!  worked a charm
:-)