Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

Patrick Reinhart patrick at reini.net
Thu Nov 27 15:11:19 UTC 2014


Inlined patch containing also additional java doc changes based on the version http://cr.openjdk.java.net/~prappo/ioutil/webrev.01/

It may contain some non proper english ;-)

-Patrick

> Am 27.11.2014 um 14:51 schrieb Alan Bateman <Alan.Bateman at oracle.com>:
> 
> On 27/11/2014 09:48, Patrick Reinhart wrote:
>> Hi Paul,
>> 
>> Seems not to work. See inline patch…
>> 
>> Patrick
>> 
> In terms of signatures then the methods look like a reasonable start. For the javadoc/spec then there are several issues that will need consideration and you might get some ideas from the javadoc that we have in the existing Files.copy methods - for example, it will need some wording about errors that happen after some (but not all) bytes/chars have been copied, some words to make it clear that the async close or either stream or thread interrupt during the copy is specified to the stream/readers/appendable involved and cannot be specified. It might also be useful to make it clear that IOE is thrown when called when the source or target is closed.
> 
> -Alan.

diff -r 194458fe7339 src/java.base/share/classes/java/io/IOUtil.java
--- a/src/java.base/share/classes/java/io/IOUtil.java	Thu Nov 27 13:50:36 2014 +0100
+++ b/src/java.base/share/classes/java/io/IOUtil.java	Thu Nov 27 16:08:09 2014 +0100
@@ -47,10 +47,28 @@
     /**
      * Reads all bytes from an input stream and writes them to an output stream.
      *
-     * @param source       the input stream to read from
-     * @param target       the output stream to write to
-     * @return             the number of bytes successfully copied
-     * @throws IOException if an I/O error occurs when reading or writing
+     * <p>  If an I/O error occurs reading from the input stream or writing to
+     * the output stream, then it may do so after the some bytes have been read 
+     * or written. Consequently the input stream may not be at end of stream and 
+     * may be in an inconsistent state. It is strongly recommended that the input
+     * and output stream be promptly closed if an I/O error occurs.
+     *
+     * <p> This method may block indefinitely reading from the input stream (or
+     * writing to the output stream). The behavior for the case that the input 
+     * and output stream is <i>asynchronously closed</i> or the thread interrupted
+     * during the copy is highly input and output stream system provider specific 
+     * and therefore not specified.
+     *
+     * @param   source
+     *          the input stream to read from
+     * @param   target
+     *          the output stream to write to
+     *
+     * @return  the number of bytes successfully copied
+     * @throws  IOException
+     *          if an I/O error occurs when reading or writing. In particular,
+     *          an <code>IOException</code> may be thrown if the output stream 
+     *          has been closed.
      */
     public static long copy(InputStream source, OutputStream target)
             throws IOException {
@@ -62,16 +80,34 @@
     /**
      * Reads all bytes from an input stream and writes them to an output stream.
      *
-     * @param source       the input stream to read from (not {@code null})
-     * @param target       the output stream to write to (not {@code null})
-     * @param buffer       the intermediate buffer to use (not {@code null},
-     *                     and {@code buffer.length >= 1})
-     * @return             the number of bytes successfully copied
-     * @throws IOException if an I/O error occurs when reading or writing
+     * <p>  If an I/O error occurs reading from the input stream or writing to
+     * the output stream, then it may do so after the some bytes have been read 
+     * or written. Consequently the input stream may not be at end of stream and 
+     * may be in an inconsistent state. It is strongly recommended that the input
+     * and output stream be promptly closed if an I/O error occurs.
+     *
+     * <p> This method may block indefinitely reading from the input stream (or
+     * writing to the output stream). The behavior for the case that the input 
+     * and output stream is <i>asynchronously closed</i> or the thread interrupted
+     * during the copy is highly input and output stream system provider specific 
+     * and therefore not specified.
+     *
+     * @param   source
+     *          the input stream to read from (not {@code null})
+     * @param   target
+     *          the output stream to write to (not {@code null})
+     * @param   buffer
+     *          the intermediate buffer to use (not {@code null},
+     *          and {@code buffer.length >= 1})
+     *
+     * @return  the number of bytes successfully copied
+     * @throws  IOException
+     *          if an I/O error occurs when reading or writing. In particular,
+     *          an <code>IOException</code> may be thrown if the output stream 
+     *          has been closed.
      */
     public static long copy(InputStream source, OutputStream target,
                             byte[] buffer) throws IOException {
-
         Objects.requireNonNull(source, "source");
         Objects.requireNonNull(target, "target");
         Objects.requireNonNull(buffer, "buffer");
@@ -92,23 +128,39 @@
     /**
      * Reads all characters from an readable and writes them to an appendable.
      *
-     * @param source the readable to read from
-     * @param target the appendable to write to
+     * <p>  If an I/O error occurs reading from the readable or writing to the 
+     * appendable, then it may do so after the some characters have been read 
+     * or written. Consequently the readable may not be at end of data and may
+     * be in an inconsistent state. It is strongly recommended that the readable
+     * and writable be promptly closed (in case of closables) if an I/O error
+     * occurs.
      *
-     * @return the number of characters successfully read and written
+     * <p> This method may block indefinitely reading from the readable (or
+     * writing to the appendable). The behavior for the case that the input and
+     * appendable is <i>asynchronously closed</i> or the thread interrupted
+     * during the copy is highly readable and appendable system provider specific 
+     * and therefore not specified.
      *
-     * @throws IOException if an I/O error occurs when reading or writing
+     * @param   source
+     *          the readable to read from
+     * @param   target
+     *          the appendable to write to
+     *
+     * @return  the number of characters successfully copied
+     *
+     * @throws  IOException
+     *          if an I/O error occurs when reading or writing.
      */
     public static long copy(Readable source, Appendable target) throws IOException {
-        long totalRead = 0L;
+        Objects.requireNonNull(source, "source");
+        Objects.requireNonNull(target, "target");
+        long copied = 0L;
         CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE);
-        int read;
-        while ((read = source.read(buffer)) > -1) {
+        for (int read; (read = source.read(buffer)) > -1; copied += read) {
 	    buffer.flip();
             target.append(buffer, 0, read);
-            totalRead += read;
         }
-        return totalRead;
+        return copied;
     }
 }
 




More information about the core-libs-dev mailing list