0

I am new to Java development so apologies in advance if I am asking something stupid.

I am trying to retrieve an image and it's thumbnail from sql database. I get data from ResultSet in BinaryStream format and then convert it to byte[].

For thumbnail it works fine and for original image too I am able to retrieve BinaryStream using getBinaryStream method But when I convert it to byte[], the array remain empty for some reason.

binaryStream = rs.getBinaryStream("image");
thumbBinaryStream = rs.getBinaryStream("thumbnail");
if (binaryStream != null) {
    // Tested on following line and I get empty imageBytes
    byte[] imageBytes = IOUtils.toByteArray(binaryStream); 
    thisRecord.put("image", DatatypeConverter.printBase64Binary(imageBytes)); // imageBytes is empty here 
}
Umair Aamir
  • 1,624
  • 16
  • 26
  • Why bother with an InputStream at all? Why not call [ResultSet.getBytes](https://docs.oracle.com/javase/10/docs/api/java/sql/ResultSet.html#getBytes(java.lang.String))? As in, `byte[] imageBytes = rs.getBytes("image");`? – VGR Jul 10 '18 at 16:27
  • I have tried both ways but `imageBytes` remains empty while if I do the same with `thumbBinaryStream` and convert it to bytes, I get the data. – Umair Aamir Jul 11 '18 at 07:08

2 Answers2

0

We probably need more information, especially about the datatypes of the columns, but maybe it helps to retrieve the stream from the BLOB like in this example:

if (rs.getMetaData().getColumnType(column) == Types.BLOB) {
        in = rs.getBlob(column).getBinaryStream();
    } else {
        in = rs.getBinaryStream(column);
    }
  • thumbnail and image both are LONGBLOB and are of exactly same type. But the problem is it works for one and not for other. – Umair Aamir Jul 10 '18 at 14:44
  • It is recommended to retrieve the stream from the result of getBlob(columnName) for large binary data, so you should give it a try. Otherwise check if there is data at all – Steffen Jacobs Jul 10 '18 at 15:00
  • I have checked by simply by running query and BLOB is there. I have tried with BLOB but no change. I am surprised that why I am getting data from thumbnail column using same code. – Umair Aamir Jul 10 '18 at 15:31
0

To be sure: Statement and ResultSet must be closed and getBinaryStream only used when the ResultSet is still open, like:

try (ResultSet rs = stmt.executeQuery()) {
    while (rs.next()) {
        InputStream binaryStream = rs.getBinaryStream("image");
        InputStream thumbBinaryStream = rs.getBinaryStream("thumbnail");
        if (binaryStream != null) {
            // Tested on following line and I get empty imageBytes
            byte[] imageBytes = IOUtils.toByteArray(binaryStream); 
            thisRecord.put("image", DatatypeConverter.printBase64Binary(imageBytes));
            boolean mustGenerateThumbnail = thumbBinaryStream == null;
            if (mustGenerateThumbnail ) {
                thumbBinaryStream = generateThumbnail(imageBytes);
            }
            byte[] thumbBytes = IOUtils.toByteArray(thumbBinaryStream);
            thisRecord.put("thumbnail", DatatypeConverter.printBase64Binary(thumbBytes));

Here we are at the error. At this point thumbBinaryStream is read till the end, so do:

            if (mustGenerateThumbnail ) {
                ByteArrayInputStream baIn = new ByteArrayInputStream(thumbBytes);
                saveThumbnailForRecordWithId(baIn, floor_drawing_id);
            }
        }
    }
}

(Here I used try-with-resources to automatically close the ResultSet even on thrown exception.)

Furthermore there is a more general class for Base64. Should you in future have the need for such.

DatatypeConverter.printBase64Binary(thumbBytes)
Base64.getEncoder().encodeToString(thumbBytes)
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • I have updated my code so that you understand my problem more clearly. I am sorry, I added unrelated code before. – Umair Aamir Jul 10 '18 at 15:28
  • And the ResultSet rs is still open it seems. It could be that no thumb gives just an empty (non-null) InputStream resulting in zero bytes. – Joop Eggen Jul 10 '18 at 15:42
  • I get data when I try to get thumbnail but I get empty byte array when I try to get image. so `byte[] thumbBytes = IOUtils.toByteArray(thumbBinaryStream);` this works fine while `byte[] imageBytes = IOUtils.toByteArray(binaryStream);` this does not. I am sure that data is in there in db. I have inserted data in same way in both fields. – Umair Aamir Jul 11 '18 at 07:11
  • I start to mistrust `generateThumbnail` as the rest of the code is plausible. Sorry to be of no help here. – Joop Eggen Jul 11 '18 at 08:13