I got my png file corrupted after calling :
BufferedImage im = ImageIO.read(inputStream);
You will find the service life cycle below :
InputStream inputStream = multipartFile.getInputStream();
throwExceptionIfImageDimensionsNotValid(inputStream);
storeIntoFileSystem(inputStream);
implementation
private void throwExceptionIfImageDimensionsNotValid(InputStream inputStream) throws IOException, StoreFileException {
BufferedImage im = ImageIO.read(inputStream);
if(isImageWidthHeightRatioOk(im.getHeight(), im.getWidth())) {
return;
} else {
throw new StoreFileException("Le rapport hauteur / largeur de limage doit etre compris entre 0.55 et 0.625");
}
}
Store file implementation :
void storeIntoFileSystem(InputStream inputStreamIn) throws IOException{
try (InputStream inputStream = inputStreamIn) {
Path targetDirectoryPath = Paths.get("Files-Upload/");
Path filePath = Paths.get("Files-Upload/").resolve("pacman_preview.png");
Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ioe) {
throw new IOException("Could not save file: " , ioe);
}
}
The problem is : When I open the file in my OS image viewer, I've got this message :
Could not load image ... Fatal error reading PNG image file. Not a PNG file
NOTE : When the throwExceptionIfImageDimensionsNotValid(inputStream) is commented, the image open's correctly.
At debug time I found that the inputStream object is modified when ImageIO.read(inputStream); is executed.
At this moment in variable eclipse view I can see bb and bs modified :
InputStream is a stream - if you read it in first method (ImageIO.read(inputStream)
), it's done, there is nothing left in the stream. You can't read it again. In that case you have to open the stream again, as below, or do some refactor to do both operations by reading InputStream only once.
InputStream inputStream = multipartFile.getInputStream();
throwExceptionIfImageDimensionsNotValid(inputStream);
inputStream = multipartFile.getInputStream();
storeIntoFileSystem(inputStream);
I should mention as well, that when you read the first stream, you should close it, before opening the new one.
As mentioned in comment, there are also streams that allow seeking or resetting. You can use such a stream here, so you don't need to create another one, but just call reset method after you read in the first method.