Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8191490

Add Reader and Writer access to java.lang.Process

    XMLWordPrintable

Details

    • CSR
    • Resolution: Approved
    • P3
    • 17
    • core-libs
    • None
    • source, binary
    • minimal
    • The new methods build on existing APIs and have minimal compatibility risk except the possibility that some existing subclass may have defined method with the same names and there is a conflict in the signatures.
    • Java API
    • SE

    Description

      Summary

      Add BufferedReader to read characters and lines from Process standard output and standard error streams and BufferedWriter to write to the Process standard input.

      Problem

      The current access to the standard streams of processes use java.io.InputStream and java.io.OutputStream. Typically, applications wrap the streams using InputStreamReader and OutputStreamWriter to convert the bytes using the system default Charset. The lack of direct access to character streams and/or lines of process input and output requires each developer to reimplement the same code needed to conveniently access the streams.

      Solution

      Add methods to Process that return BufferedReader for the process output and error streams and a method to return a BufferedWriter for the standard input to the process using the system property native.encoding for Charset. Additional methods allow the Charset to be supplied.

      BufferedReader provides convenient access to individual lines of output from the process and a fluent interface to utilize java.util.Stream functions to process process output as streams of strings.

      BufferedWriter provides methods to write characters, arrays of characters and strings to the process using the native.encoding to encode characters to bytes.

      The system property native.encoding is used as the default value for the Charset for the methods that do not provide the Charset explicitly.

      I/O errors that occur on the underlying byte streams throw IOException and can be handled by the caller of the BufferedReader and BufferedWriters.

      Specification

      Add a new intro sentence in the class javadoc after the mention of the get*methods.

       * The I/O streams of characters and lines can be written and read using the methods
       * {@link #outputWriter()}, {@link #outputWriter(Charset)}},
       * {@link #inputReader()}, {@link #inputReader(Charset)},
       * {@link #errorReader()}, and {@link #errorReader(Charset)}.

      New methods in java.lang.Process:

          /**
           * Returns a {@link BufferedReader BufferedReader} connected to the standard
           * output of the process. The {@link Charset} for the native encoding is used
           * to read characters, lines, or stream lines from standard output.
           *
           * <p>This method delegates to {@link #inputReader(Charset)} using the
           * {@link Charset} named by the {@code native.encoding} system property.
           * If the {@code native.encoding} is not a valid charset name or not supported
           * the {@link Charset#defaultCharset()} is used.
           *
           * @return a {@link BufferedReader BufferedReader} using the
           *          {@code native.encoding} if supported, otherwise, the
           *          {@link Charset#defaultCharset()}
           * @since 17
           */
          public final BufferedReader inputReader() {...}
      
          /**
           * Returns a {@link BufferedReader BufferedReader} connected to the
           * standard output of this process using a Charset.
           * The {@code BufferedReader} can be used to read characters, lines,
           * or stream lines of the standard output.
           *
           * <p>Characters are read by an InputStreamReader that reads and decodes bytes
           * from this process {@link #getInputStream()}. Bytes are decoded to characters
           * using the {@code charset}; malformed-input and unmappable-character
           * sequences are replaced with the charset's default replacement.
           * The {@code BufferedReader} reads and buffers characters from the InputStreamReader.
           *
           * <p>The first call to this method creates the {@link BufferedReader BufferedReader},
           * if called again with the same {@code charset} the same {@code BufferedReader} is returned.
           * It is an error to call this method again with a different {@code charset}.
           *
           * <p>If the standard output of the process has been redirected using
           * {@link ProcessBuilder#redirectOutput(Redirect) ProcessBuilder.redirectOutput}
           * then the {@code InputStreamReader} will be reading from a
           * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
           *
           * <p>Otherwise, if the standard error of the process has been redirected using
           * {@link ProcessBuilder#redirectErrorStream(boolean)
           * ProcessBuilder.redirectErrorStream} then the input reader returned by
           * this method will receive the merged standard output and the standard error
           * of the process.
           *
           * @apiNote
           * Using both {@link #getInputStream} and {@link #inputReader(Charset)} has
           * unpredictable behavior since the buffered reader reads ahead from the
           * input stream.
           *
           * <p>When the process has terminated, and the standard input has not been redirected,
           * reading of the bytes available from the underlying stream is on a best effort basis and
           * may be unpredictable.
           *
           * @param charset the {@code Charset} used to decode bytes to characters
           * @return a {@code BufferedReader} for the standard output of the process using the {@code charset}
           * @throws NullPointerException if the {@code charset} is {@code null}
           * @throws IllegalStateException if called more than once with different charset arguments
           * @since 17
           */
          public final BufferedReader inputReader(Charset charset) {...}
      
          /**
           * Returns a {@link BufferedReader BufferedReader} connected to the standard
           * error of the process. The {@link Charset} for the native encoding is used
           * to read characters, lines, or stream lines from standard error.
           *
           * <p>This method delegates to {@link #errorReader(Charset)} using the
           * {@link Charset} named by the {@code native.encoding} system property.
           * If the {@code native.encoding} is not a valid charset name or not supported
           * the {@link Charset#defaultCharset()} is used.
           *
           * @return a {@link BufferedReader BufferedReader} using the
           *          {@code native.encoding} if supported, otherwise, the
           *          {@link Charset#defaultCharset()}
           * @since 17
           */
          public final BufferedReader errorReader() {...}
      
          /**
           * Returns a {@link BufferedReader BufferedReader} connected to the
           * standard error of this process using a Charset.
           * The {@code BufferedReader} can be used to read characters, lines,
           * or stream lines of the standard error.
           *
           * <p>Characters are read by an InputStreamReader that reads and decodes bytes
           * from this process {@link #getErrorStream()}. Bytes are decoded to characters
           * using the {@code charset}; malformed-input and unmappable-character
           * sequences are replaced with the charset's default replacement.
           * The {@code BufferedReader} reads and buffers characters from the InputStreamReader.
           *
           * <p>The first call to this method creates the {@link BufferedReader BufferedReader},
           * if called again with the same {@code charset} the same {@code BufferedReader} is returned.
           * It is an error to call this method again with a different {@code charset}.
           *
           * <p>If the standard error of the process has been redirected using
           * {@link ProcessBuilder#redirectError(Redirect) ProcessBuilder.redirectError} or
           * {@link ProcessBuilder#redirectErrorStream(boolean) ProcessBuilder.redirectErrorStream}
           * then the {@code InputStreamReader} will be reading from a
           * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
           *
           * @apiNote
           * Using both {@link #getErrorStream} and {@link #errorReader(Charset)} has
           * unpredictable behavior since the buffered reader reads ahead from the
           * error stream.
           *
           * <p>When the process has terminated, and the standard error has not been redirected,
           * reading of the bytes available from the underlying stream is on a best effort basis and
           * may be unpredictable.
           *
           * @param charset the {@code Charset} used to decode bytes to characters
           * @return a {@code BufferedReader} for the standard error of the process using the {@code charset}
           * @throws NullPointerException if the {@code charset} is {@code null}
           * @throws IllegalStateException if called more than once with different charset arguments
           * @since 17
           */
          public final BufferedReader errorReader(Charset charset) {...}
      
          /**
           * Returns a {@code BufferedWriter} connected to the normal input of the process
           * using the native encoding.
           * Writes text to a character-output stream, buffering characters so as to provide
           * for the efficient writing of single characters, arrays, and strings.
           *
           * <p>This method delegates to {@link #outputWriter(Charset)} using the
           * {@link Charset} named by the {@code native.encoding} system property.
           * If the {@code native.encoding} is not a valid charset name or not supported
           * the {@link Charset#defaultCharset()} is used.
           *
           * @return a {@code BufferedWriter} to the standard input of the process using the charset
           *          for the {@code native.encoding} system property
           * @since 17
           */
          public final BufferedWriter outputWriter() {...}
      
          /**
           * Returns a {@code BufferedWriter} connected to the normal input of the process
           * using a Charset.
           * Writes text to a character-output stream, buffering characters so as to provide
           * for the efficient writing of single characters, arrays, and strings.
           *
           * <p>Characters written by the writer are encoded to bytes using {@link OutputStreamWriter}
           * and the {@link Charset} are written to the standard input of the process represented
           * by this {@code Process}.
           * Malformed-input and unmappable-character sequences are replaced with the charset's
           * default replacement.
           *
           * <p>The first call to this method creates the {@link BufferedWriter BufferedWriter},
           * if called again with the same {@code charset} the same {@code BufferedWriter} is returned.
           * It is an error to call this method again with a different {@code charset}.
           *
           * <p>If the standard input of the process has been redirected using
           * {@link ProcessBuilder#redirectInput(Redirect)
           * ProcessBuilder.redirectInput} then the {@code OutputStreamWriter} writes to a
           * <a href="ProcessBuilder.html#redirect-input">null output stream</a>.
           *
           * @apiNote
           * A {@linkplain BufferedWriter} writes characters, arrays of characters, and strings.
           * Wrapping the {@link BufferedWriter} with a {@link PrintWriter} provides
           * efficient buffering and formatting of primitives and objects as well as support
           * for auto-flush on line endings.
           * Call the {@link BufferedWriter#flush()} method to flush buffered output to the process.
           * <p>
           * When writing to both {@link #getOutputStream()} and either {@link #outputWriter()}
           * or {@link #outputWriter(Charset)}, {@linkplain BufferedWriter#flush BufferedWriter.flush}
           * should be called before writes to the {@code OutputStream}.
           *
           * @param charset the {@code Charset} to encode characters to bytes
           * @return a {@code BufferedWriter} to the standard input of the process using the {@code charset}
           * @throws NullPointerException if the {@code charset} is {@code null}
           * @throws IllegalStateException if called more than once with different charset arguments
           * @since 17
           */
          public final BufferedWriter outputWriter(Charset charset) {...}
      

      Attachments

        Issue Links

          Activity

            People

              rriggs Roger Riggs
              rriggs Roger Riggs
              Alan Bateman, Brian Burkhalter
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: