I am seeing a strange behavior with ImageIO.read() method.
I pass the InputStream to this method and when I try to read it for the second time it fails to read and returns null.
I am trying to upload images to the Amazon S3 and I want to create 3 version of the image. The original and 2 thumbnails. My problem is that when I want to create the 2 thumbnails I need to read the InputStream using the ImageIO.read(). If I run this method 2 for the same InputStream I get the null for the second read.
I can circumvent this problem by reading only one and passing the same BufferedImage to the scaling method. However I still need the InputStream that my method gets to pass to the AmazonS3 services in other to upload the original file as well.
So my question is does anyone have any idea what happens to the input stream after ImageIO reads it for the first time?
Code sample below
public String uploadImage(InputStream stream, String filePath, String fileName, String fileExtension) {
try {
String originalKey = filePath + fileName + "." + fileExtension;
String smallThumbKey = filePath + fileName + ImageConst.Path.SMALL_THUMB + "." + fileExtension;
String largetThumbKey = filePath + fileName + ImageConst.Path.LARGE_THUMB + "." + fileExtension;
BufferedImage image = ImageIO.read(stream);
InputStream smallThumb = createSmallThumb(image, fileExtension);
InputStream largeThumb = createLargeThumb(image, fileExtension);
uploadFileToS3(originalKey, stream);
uploadFileToS3(smallThumbKey, smallThumb);
uploadFileToS3(largetThumbKey, largeThumb);
return originalKey;
} catch (IOException ex) {
Logger.getLogger(ManageUser.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
I suppose, you could wrap your original input stream in a BufferedInputStream and use mark() to save the starting position within the stream, and reset() to return to it.
To fully answer your question: every stream gets read sequentially (often there is some kind of internal pointer pointing to the current position). After the first
ImageIO.read(), the stream is read until its end, thus, any further read operation won’t return any data (usually -1 to indicate the end of the stream). Using mark() you can save a certain position and later on return to it using reset().