Handling OracleConversionInputStream with images...
Hello,
I'm trying to read images from DB using:
InputStream is = resultSet.getBinaryStream(1);
It is OK for DB such as MySQL.
But if I connect to Oracle DB 10g the returned input stream is of type OracleConversionInputStream and must be read chunk by chunk.
If I write 'is' into a file everything is OK: the file is a good JPEG:
FileOutputStream fos = new FileOutputStream("/Users/myaccount/Image.jpg");
byte[] data = new byte[1024];
int i = 0;
while((i = is.read(data)) != -1)
{
fos.write(data, 0, i);
}
fos.close();
But if I use it through ImageIO null is returned:
MediaTracker mediaTracker = new MediaTracker(container);
Image image = ImageIO.read(is);
// Here image is null
mediaTracker.addImage(image, 0);
mediaTracker.waitForID(0);
mediaTracker.removeImage(image, 0);
And if I then try to write it down to a file it fails:
if(null==image)
{
if(is.markSupported()) // Useless since not supported by OracleConversionInputStream
is.reset();
FileOutputStream fos = new FileOutputStream("/Users/myaccount/Image.jpg");
byte[] data = new byte[1024];
int i = 0;
while((i = is.read(data)) != -1) // Never entered: returns -1 on first call
{
fos.write(data, 0, i);
}
fos.close();
}
How can I write this image into a Image object?
Or how can I reset the InputStream since OracleConversionInputStream since is.reset throws an exception (is.markSupported() returns false)?
Regards,
L.
[1616 byte] By [
JolieLaraa] at [2007-11-27 5:54:41]

I ignore the fact that reading the image via ImageIO looks suspect to me ...
> How can I write this image into a Image object?
Why don't you use ImageIO to write the BufferedImage you get when reading?
> Or how can I reset the InputStream
Obviously not at all cause the Oracle driver seems to mind asking the server again or buffering the stream more than necessary for simple, sequential reading.
You _could_ read data into a ByteArrayOutputStream and use the result as input source for ImageIO, but I'd rather cut off my leg with an axe than do this.
> I ignore the fact that reading the image via ImageIO
> looks suspect to me ...
>
> > How can I write this image into a Image object?
>
> Why don't you use ImageIO to write the BufferedImage
> you get when reading?
I'm not sure to understand your question: that's what ImageIO.read is intended to, no?
ImageIO.read returns a BufferedImage that I put on a JLabel in a JPanel to list thumbnails of all images in the database...
But I don't know how to create a BufferedImage from an InputStream that's why I use ImageIO.read that fails with Oracle DB...
What is more I need the InputStream to parse IPTC data later for JPEG data with code like that:
ImageInputStream imageInputStream = ImageIO.createImageInputStream(is);
Iterator readers = ImageIO.getImageReaders(imageInputStream);
if(null!=readers&&readers.hasNext())
{
ImageReader reader = (ImageReader)readers.next();
reader.setInput(imageInputStream);
String szFormat = reader.getFormatName();
if(szFormat.equalsIgnoreCase("JPEG"))
parseIPTC(is);
reader.dispose();
}
imageInputStream.close();
And again it fails since is.reset() does not work with Oracle DB...
I'm stuck...
>
> > Or how can I reset the InputStream
>
> Obviously not at all cause the Oracle driver seems to
> mind asking the server again or buffering the stream
> more than necessary for simple, sequential reading.
>
> You _could_ read data into a ByteArrayOutputStream
> and use the result as input source for ImageIO, but
> I'd rather cut off my leg with an axe than do this.
I see. In this case I'd suggest writing the stream's contents into a (temporary) file on disk and make ImageIO read the file instead.
That's precisely what I ended up doing but it is far from efficient since the data are read twice and written once...
Nobody has ever encountered the need of reading data from a DB and displaying them anywhere at once?
And it does not seem to be documented at Sun's...
Nor it is at Oracle's either.
But thanks for your help!
> That's precisely what I ended up doing but it is far
> from efficient since the data are read twice and written once...
Yes, but I don't think disc I/O will be too much of a problem. I wonder whether ImageIO fails for Oracle's stream because of the missing mark support or because of something else going wrong. Do you have any hint?
For if it was missing mark support, you could wrap a buffering stream doing mark/reset around the original one.
> Nobody has ever encountered the need of reading data
> from a DB and displaying them anywhere at once?
Sure. I once had created a servlet which delivered images for a website right out of Oracle BLOBs. It was a major pain in the ***, but worked.
> Nor it is at Oracle's either.
You could file a bug report at Oracle, though.
> > That's precisely what I ended up doing but it is
> far
> > from efficient since the data are read twice and
> written once...
>
> Yes, but I don't think disc I/O will be too much of a
> problem. I wonder whether ImageIO fails for Oracle's
> stream because of the missing mark support or because
> of something else going wrong. Do you have any hint?
Not for now, sorry...
> For if it was missing mark support, you could wrap a
> buffering stream doing mark/reset around the original
> one.
Yes but since wrappers such as ByteArrayInputStream or BufferedInputStream use the underlying InputStream I guess they won't support marks either...
>
> Nobody has ever encountered the need of reading
> data
> from a DB and displaying them anywhere at once?
>
> Sure. I once had created a servlet which delivered
> images for a website right out of Oracle BLOBs. It
> was a major pain in the ***, but worked.
>
> > Nor it is at Oracle's either.
>
> You could file a bug report at Oracle, though.
Yes but I'm using oracle:thin JDBC driver and this is perhaps one of its limitations.
Furthermore Sun's Java doc says mark supporting is not compulsory then oracle:thin driver may not be wrong...
Anyway thanks again for your help!
Regards,
L.
> Yes but since wrappers such as ByteArrayInputStream
> or BufferedInputStream use the underlying InputStream
> I guess they won't support marks either...
You could create a buffering stream of your own if you want to make sure, that should not be too difficult.
> Yes but I'm using oracle:thin JDBC driver and this is perhaps one of its limitations.
We've been using the thin driver for several years but switched to a third-party driver for several other bugs and performance issues 1 or 2 years ago.
> Furthermore Sun's Java doc says mark supporting is
> not compulsory then oracle:thin driver may not be wrong...
Right, the stream's behaviour is perfectly legal in this case.