FileInputStream.available() is only guaranteed to tell you how many bytes are immediately available for reading without blocking -- probably one buffer worth. You need to copy *all* of the bytes to the output stream -- something like this (but doing it from memory so might not be correct):
FileInputStream in = new FileInputStream(pdf_path); OutputStream out = ...; // whatever output stream you want byte buffer[] = new byte[BUFFER_SIZE]; int bytes; while (true) { bytes = in.read(buffer, 0, BUFFER_SIZE]); if (bytes < 0) { break; } out.write(buffer, 0, bytes); } out.flush(); out.close(); in.close(); Define BUFFER_SIZE based on a balance between memory occupancy and speed -- probably something like 4096 would serve as a good starting point, especially if your PDFs are small and might fit in a single buffer. Craig On Wed, 4 Aug 2004 10:37:18 +0200 , Otto, Frank <[EMAIL PROTECTED]> wrote: > Hi, > > I have written an action class to show the pdf, but the pdf is corrupt. > > Do I something wrong? > > .... > FileInputStream fis = new FileInputStream(pdf_path); > int anz = fis.available(); > byte[] data = new byte[anz]; > fis.read(data); > > ByteArrayOutputStream baos = new ByteArrayOutputStream(); > baos.write(data, 0, anz); > baos.flush(); > baos.close(); > > response.setContentType("application/pdf"); > response.setHeader("Pragma", "public"); > response.setHeader("Content-Disposition", "inline;filename=offer.pdf"); > response.setContentLength(anz); > > ServletOutputStream out = response.getOutputStream(); > baos.writeTo(out); > out.flush(); > .... > return null; > > kind regards, > > frank > > > -----Ursprüngliche Nachricht----- > > Von: Frank Zammetti [mailto:[EMAIL PROTECTED] > > Gesendet: Dienstag, 3. August 2004 15:41 > > An: [EMAIL PROTECTED] > > Betreff: RE: struts and iText > > > > > > Another option: write the PDF out to a database BLOB field, > > then create an > > Action to retrieve that field. This I think gives you the > > best of all > > worlds. If you structure the table properly, you can share > > the PDF across > > various requests/users and you can even avoid PDF generation > > potentially by > > seeing if an appropriate PDF exists in the table already. A > > simple timed > > stored procedure should serve as a good cleanup mechanism. > > Just to save you > > some time, here's an Action I use in a system I wrote that > > retrieves any > > BLOB field and returns it... I'll have to remove some parts > > and just give > > you comments because it uses two custom classes for database > > access, and I > > don't want to post that much code here, the other classes are a bit > > larger... I'll also simplify the error handling, since it's > > custom as well, > > but I think the point will come across... The only note I > > think is that > > this assumes that the table the BLOB is retrieved from has a > > field with the > > same name as the BLOB field with _ctype appended, and this > > contains the > > content type to return. > > > > > > import java.io.ByteArrayOutputStream; > > import java.sql.Blob; > > import javax.servlet.http.HttpServletRequest; > > import javax.servlet.http.HttpServletResponse; > > import javax.servlet.ServletOutputStream; > > import org.apache.struts.action.Action; > > import org.apache.struts.action.ActionForm; > > import org.apache.struts.action.ActionForward; > > import org.apache.struts.action.ActionMapping; > > > > public class BLOBServerAction extends Action { > > > > public ActionForward execute(ActionMapping mapping, > > ActionForm inForm, > > HttpServletRequest request, HttpServletResponse response) > > throws Exception { > > > > try { > > > > String bTable = "the_table_the_blob_is_in"; > > String bField = "the_field_the_blob_is_in"; > > String bQuery = "where_clause_to_select_proper_record; > > > > String sql = "select " + bField + "," + bField + > > "_ctype from " + > > bTable + " where " + bQuery; > > Blob blob = null; > > String contentType = null; > > byte[] bytes = null; > > > > ResultSet rs = doSelect(sql); // Insert database access > > here, just use > > the above constructed SQL string > > while (rs.next()) { > > contentType = rs.getString(bField + "_ctype"); > > blob = rs.getBlob(bField); > > } > > > > ServletOutputStream out = response.getOutputStream(); > > > > response.setContentType(contentType); > > if (blob != null) { > > bytes = blob.getBytes(1, (int)(blob.length())); > > ByteArrayOutputStream ba = new ByteArrayOutputStream(); > > ba.write(bytes, 0, bytes.length); > > ba.writeTo(out); > > } > > out.flush(); > > > > } catch (Exception e) { > > > > e.printStackTrace(); > > > > } > > > > return null; > > > > } // End process() > > > > } > > > > > > Hope that helps, if you go this route. > > > > Frank W. Zammetti > > Chief Software Architect > > Omnytex Technologies > > www.omnytex.com > > > > > > >From: "Jesse Alexander (KXT)" <[EMAIL PROTECTED]> > > >Reply-To: "Struts Users Mailing List" <[EMAIL PROTECTED]> > > >To: Struts Users Mailing List <[EMAIL PROTECTED]> > > >Subject: RE: struts and iText > > >Date: Tue, 3 Aug 2004 10:49:08 +0200 > > > > > >Well,... > > > > > >If you already have the PDF generated, why not directly > > write it to the > > >response(and in this way to the browser)? > > > > > >To fulfill your use case as described. > > >Your action generates the PDF and caches it somewhere. Then > > it will forward > > >to the JSP-File containing the message and the link. This > > link either > > >points to a Struts-Action or a plain servlet. This > > target-Servlet (or > > >Action) retrieves the cached PDF and sends it to the browser. > > >Where to cache? > > >a) File-System > > > - you need a writable location and remember to install > > some cleaning > > >mechanism > > > - the link presented could be just the reference to the > > cached file if > > >that directory > > > readable by the webserver > > >b) user-session > > > - dangerous in a clustered environment (too much stuff to > > propagate > > >around) > > > - memory usage (usually the recommendation is not to use > > more than 4K in > > >session...) > > > - PDF only available to original user > > > - easy to program > > >c) separate cache > > > - adds another component to your app (DO NOT roll your own > > cache, there > > >are quite a > > > number of tested cache-libraries) > > > - could make the PDF available also to other users (depends on the > > >use-case and the > > > cache-library) > > > > > >hope this helps > > >Alexander > > > > > > > > >-----Original Message----- > > >From: Otto, Frank [mailto:[EMAIL PROTECTED] > > >Sent: Tuesday, August 03, 2004 9:18 AM > > >To: '[EMAIL PROTECTED]' > > >Subject: struts and iText > > > > > >Hi, > > > > > >I have generated a pdf with iText. In my action class I want > > to write it in > > >the response object. > > > > > >The result should be a jsp-page with content "pdf generated > > successful" and > > >a link to this pdf. The pdf should be shown in a new browser > > window too. > > > > > >Has someone do this? How can I do this? > > > > > > > > >kind regards, > > > > > >frank > > > > > >--------------------------------------------------------------------- > > >To unsubscribe, e-mail: [EMAIL PROTECTED] > > >For additional commands, e-mail: [EMAIL PROTECTED] > > > > > > > _________________________________________________________________ > > Planning a family vacation? Check out the MSN Family Travel guide! > > http://dollar.msn.com > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: [EMAIL PROTECTED] > > For additional commands, e-mail: [EMAIL PROTECTED] > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]