This is probably pretty basic...just not sure what the right thing is. We've got some images that get generated on our web app, and we're going to try storing them in the database instead of on the webserver. I've got the BLOB stuff figured out with Oracle JDBC, but I'm looking at the point where we generate the image and write it out to a file:
jpegOutput is a File object, and tallerImage is a BufferedImage (we generate a JPEG and a PNG of the same image, so we originally would write two files out to the filesystem. My JDBC code for writing images to the database can handle loading an image from file and inserting it like this:
I want to skip the step of writing the image out to the filesystem, so obviously I need to use ImageIO's write method that writes out to an OutputStream, and then pipe that OutputStream into the InputStream needed by the JDBC code above. How do I do that? Thanks...
Here's my problem: we used to write out these dynamically generated images to flat files on the webserver's filesystem, but we're moving to Oracle and want to store them in the database. I'd like to be able to generate them in memory and then write them directly to the database without saving them to temp files first, but I've tried so many different things, and it looks like I'll need to write them to temp files, as lame as that is.
The reason is this: java.sql.PreparedStatement's setBinaryStream method takes a (binary) InputStream and the number of bytes of the image. When we generate these images on our end, they're in a java.awt.image.BufferedImage object, and from there we write them out to two files: one in PNG format, and the other in JPEG format. When you use ImageIO's write method for this, it writes them to an OutputStream. So I was trying to figure out a way to channel that OutputStream to the InputStream that the PreparedStatement requires without writing it out to file with a FileOutputStream and then reading it back in with a FileInputStream.
In trying to find a way, I stumbled upon PipedInputStream and PipedOutputStream, but I never got them to work for me due exceptions resulting from broken pipes. I understand threads and producer/consumer stuff a bit, but maybe not enough...or maybe when the PreparedStatement was trying to read the InputStream, it didn't like waiting (i.e. assumed that the pipe was broken since it had to wait). Or maybe that's a bad hypothesis.
Anyway, as I said, I think I'm just going to have to write the images out to temp files, even though that could slow things down quite a bit. ...I came back to edit this...looks like reading the images in from file often takes over a full second, whereas storing them in the database over the network is a tenth or a hundredth of a second! This is not cool...why can't there be an easier way to get these stinkin' bytes into the database? [ December 22, 2004: Message edited by: Stephen Huey ]
Let ImageIO's write method write out the BufferedImage to a ByteArrayOutputStream, then call that class's toByteArray() method and initialize a ByteArrayInputStream with that object. Then the PreparedStatement's setBinaryStream method will have an InputStream...