<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    Hi Martin,<br>
    <br>
    It is reasonable to assume creating an output stream may also throw
    <code>IOException</code>. The code handles this situation but it
    doesn't re-throw the exception because its contract states it
    returns null in this case.<br>
    <br>
    The third option looks as the best solution. Any usages of the API
    are still expected to handle <code>IOException</code>.<br>
    <br>
    At the same time, there could be reasons why it's not the best
    choice. I didn't look thoroughly into the code.<br>
    <br>
    <br>
    Regards,<br>
    Alexey<br>
    <br>
    <div class="moz-cite-prefix">On 13/09/2022 10:53, Martin
      Desruisseaux wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:87caf995-97f8-d816-821a-66a2d79fc237@geomatys.com">
      
      <p>Hello all</p>
      <p>The <font face="monospace">ImageIO</font> class contains the
        following method (copying only relevant parts). The key point to
        notice is that any <font face="monospace">IOException</font> is
        assumed to be a problem with the cache file, never with the main
        output stream:</p>
      <p><br>
      </p>
      <blockquote>
        <pre>/**
 * …snip…
 * @return an {@code ImageOutputStream}, or {@code null}.
 * …snip…
 * @exception IOException if a cache file is needed but cannot be created.
 */
public static ImageOutputStream createImageOutputStream(Object output) throws IOException {
    // …snip…
    try {
        return spi.createOutputStreamInstance(output,
                                              usecache,
                                              getCacheDirectory());
    } catch (IOException e) {
        throw new IIOException("Can't create cache file!", e);
    }
    // …snip…
    return null;
}
</pre>
      </blockquote>
      <p><br>
      </p>
      <p>In the particular case where the output is a <font face="monospace">java.io.File</font>, the SPI implementation
        is as below (augmented with a copy of the Javadoc from public
        API). Note that the javadoc does not mention that <font face="monospace">ImageOutputStreamSpi.createOutputStreamInstance(…)</font>
        may return null.<br>
      </p>
      <p><br>
      </p>
      <blockquote>
        <pre>/**
 * …snip…
 * @return an {@code ImageOutputStream} instance.
 * …snip…
 * @exception IOException if a cache file is needed but cannot be created.
 */
public ImageOutputStream createOutputStreamInstance(…snip…) throws IOException {
    // …snip…
    try {
        return new FileImageOutputStream((File)output);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
    // …snip…
}
</pre>
      </blockquote>
      <p><br>
      </p>
      <p>In case of failure to create the output stream, <font face="monospace">ImageIO.write(…)</font> throws an exception
        with the "Can't create an ImageOutputStream!" message, but we
        don't know why. The cause (for example no space left on device)
        is hidden in the <font face="monospace">System.err</font>
        outputs. If we replace the <font face="monospace">com.sun.imageio.spi.FileImageOutputStreamSpi</font>
        implementation by our own provider propagating the <font face="monospace">IOException</font> instead of returning null,
        it is slightly better but the exception is caught by <font face="monospace">ImageIO.createImageOutputStream</font> and
        rethrown with the misleading "Can't create cache file!" message.
        The consequence is that when writing millions of images (e.g.
        Earth Observation data) and the process fails somewhere at <font face="monospace">ImageOutputStream</font> creation time, it is
        currently difficult to identify the cause.</p>
      <p>Possible actions for improving the situation could be (from
        less disruptive to most disruptive):</p>
      <ul>
        <li>Replace the <font face="monospace">e.printStackTrace()</font>
          call by the use of logger.</li>
        <li>Remove the try … catch block in <font face="monospace">ImageIO.createImageOutputStream(…)</font>,
          so if an SPI choose to throw <font face="monospace">IOException</font>
          (at the cost of violating current Image I/O contract), <font face="monospace">ImageIO</font> does not misleadingly said
          that it is a problem with the cache.</li>
        <li>Modify <font face="monospace">ImageIO.createImageOutputStream(…)</font>
          contract by saying that <font face="monospace">IOException</font>
          may be thrown because of failure to create the main output
          stream, not only because of failure to create the cache file.
          Adapt <font face="monospace">FileImageOutputStreamSpi</font>
          implementation accordingly.<br>
        </li>
      </ul>
      <p>Is there any thought about what would be reasonable, what would
        be too much disruption?</p>
      <p>    Regards,</p>
      <p>        Martin</p>
      <p><br>
      </p>
    </blockquote>
    <br>
  </body>
</html>