What does control caching means in ImageIO read

2019-07-23 12:24发布

问题:

My only fear of using BufferedImage object is that for a very large image of say 60000x32000 it will result in JVM shutting down with OOM on a limited JVM heap space. However, JavaDocs of ImageIO.read method says something about "control caching".

What is control caching in this context?

Does that mean ImageIO.read uses caching of image on disk for large image?

Refer to JavaDocs and ImageIO.read method below:

       /**
         * Returns a <code>BufferedImage</code> as the result of decoding
         * a supplied <code>File</code> with an <code>ImageReader</code>
         * chosen automatically from among those currently registered.
         * The <code>File</code> is wrapped in an
         * <code>ImageInputStream</code>.  If no registered
         * <code>ImageReader</code> claims to be able to read the
         * resulting stream, <code>null</code> is returned.
         *
         * <p> The current cache settings from <code>getUseCache</code>and
         * <code>getCacheDirectory</code> will be used to control caching in the
         * <code>ImageInputStream</code> that is created.
         *
         * <p> Note that there is no <code>read</code> method that takes a
         * filename as a <code>String</code>; use this method instead after
         * creating a <code>File</code> from the filename.
         *
         * <p> This method does not attempt to locate
         * <code>ImageReader</code>s that can read directly from a
         * <code>File</code>; that may be accomplished using
         * <code>IIORegistry</code> and <code>ImageReaderSpi</code>.
         *
         * @param input a <code>File</code> to read from.
         *
         * @return a <code>BufferedImage</code> containing the decoded
         * contents of the input, or <code>null</code>.
         *
         * @exception IllegalArgumentException if <code>input</code> is
         * <code>null</code>.
         * @exception IOException if an error occurs during reading.
         */
        public static BufferedImage read(File input) throws IOException {
            if (input == null) {
                throw new IllegalArgumentException("input == null!");
            }
            if (!input.canRead()) {
                throw new IIOException("Can't read input file!");
            }

            ImageInputStream stream = createImageInputStream(input);
            if (stream == null) {
                throw new IIOException("Can't create an ImageInputStream!");
            }
            BufferedImage bi = read(stream);
            if (bi == null) {
                stream.close();
            }
            return bi;
        }

回答1:

In this context, it just means the read method will use the settings from getUseCache and getCacheDirectory to control if caching will be allowed (getUseCache) and if so, where it can store temporary files (getCacheDirectory).

The caching in ImageIO is nothing spectacular and probably only there for dealing with non-seekable streams. For example, when ImageIO needs to determine the size of the image, it may need to read a significant portion of the stream. It then may need to re-read that part of the stream again to do the actual decoding.

For files and streams that support seeking, this is no issue as you can just re-read an earlier part when starting the decode. For say a HTTP stream, there is no such option and in those cases part of the stream may need to be stored somewhere in order to decode it later. This can be in memory (MemoryCacheImageInputStream) or in a temporary file (FileCacheImageInputStream).

Which type of stream is used is left up to the ImageIO class which dynamically decides this based on the cache settings and the underlying media.

So, I donot think this will help you when dealing with very large images. You will still need to make sure the VM has sufficient space for decoding them.