src/java.base/share/classes/java/io/PipedInputStream.java
changeset 58288 48e480e56aad
parent 58242 94bb65cb37d3
child 58679 9c3209ff7550
equal deleted inserted replaced
58287:a7f16447085e 58288:48e480e56aad
    28 /**
    28 /**
    29  * A piped input stream should be connected
    29  * A piped input stream should be connected
    30  * to a piped output stream; the piped  input
    30  * to a piped output stream; the piped  input
    31  * stream then provides whatever data bytes
    31  * stream then provides whatever data bytes
    32  * are written to the piped output  stream.
    32  * are written to the piped output  stream.
    33  * Typically, data is read from a <code>PipedInputStream</code>
    33  * Typically, data is read from a {@code PipedInputStream}
    34  * object by one thread  and data is written
    34  * object by one thread  and data is written
    35  * to the corresponding <code>PipedOutputStream</code>
    35  * to the corresponding {@code PipedOutputStream}
    36  * by some  other thread. Attempting to use
    36  * by some  other thread. Attempting to use
    37  * both objects from a single thread is not
    37  * both objects from a single thread is not
    38  * recommended, as it may deadlock the thread.
    38  * recommended, as it may deadlock the thread.
    39  * The piped input stream contains a buffer,
    39  * The piped input stream contains a buffer,
    40  * decoupling read operations from write operations,
    40  * decoupling read operations from write operations,
    78 
    78 
    79     /**
    79     /**
    80      * The index of the position in the circular buffer at which the
    80      * The index of the position in the circular buffer at which the
    81      * next byte of data will be stored when received from the connected
    81      * next byte of data will be stored when received from the connected
    82      * piped output stream. <code>in&lt;0</code> implies the buffer is empty,
    82      * piped output stream. <code>in&lt;0</code> implies the buffer is empty,
    83      * <code>in==out</code> implies the buffer is full
    83      * {@code in==out} implies the buffer is full
    84      * @since   1.1
    84      * @since   1.1
    85      */
    85      */
    86     protected int in = -1;
    86     protected int in = -1;
    87 
    87 
    88     /**
    88     /**
    91      * @since   1.1
    91      * @since   1.1
    92      */
    92      */
    93     protected int out = 0;
    93     protected int out = 0;
    94 
    94 
    95     /**
    95     /**
    96      * Creates a <code>PipedInputStream</code> so
    96      * Creates a {@code PipedInputStream} so
    97      * that it is connected to the piped output
    97      * that it is connected to the piped output
    98      * stream <code>src</code>. Data bytes written
    98      * stream {@code src}. Data bytes written
    99      * to <code>src</code> will then be  available
    99      * to {@code src} will then be  available
   100      * as input from this stream.
   100      * as input from this stream.
   101      *
   101      *
   102      * @param      src   the stream to connect to.
   102      * @param      src   the stream to connect to.
   103      * @throws     IOException  if an I/O error occurs.
   103      * @throws     IOException  if an I/O error occurs.
   104      */
   104      */
   105     public PipedInputStream(PipedOutputStream src) throws IOException {
   105     public PipedInputStream(PipedOutputStream src) throws IOException {
   106         this(src, DEFAULT_PIPE_SIZE);
   106         this(src, DEFAULT_PIPE_SIZE);
   107     }
   107     }
   108 
   108 
   109     /**
   109     /**
   110      * Creates a <code>PipedInputStream</code> so that it is
   110      * Creates a {@code PipedInputStream} so that it is
   111      * connected to the piped output stream
   111      * connected to the piped output stream
   112      * <code>src</code> and uses the specified pipe size for
   112      * {@code src} and uses the specified pipe size for
   113      * the pipe's buffer.
   113      * the pipe's buffer.
   114      * Data bytes written to <code>src</code> will then
   114      * Data bytes written to {@code src} will then
   115      * be available as input from this stream.
   115      * be available as input from this stream.
   116      *
   116      *
   117      * @param      src   the stream to connect to.
   117      * @param      src   the stream to connect to.
   118      * @param      pipeSize the size of the pipe's buffer.
   118      * @param      pipeSize the size of the pipe's buffer.
   119      * @throws     IOException  if an I/O error occurs.
   119      * @throws     IOException  if an I/O error occurs.
   125          initPipe(pipeSize);
   125          initPipe(pipeSize);
   126          connect(src);
   126          connect(src);
   127     }
   127     }
   128 
   128 
   129     /**
   129     /**
   130      * Creates a <code>PipedInputStream</code> so
   130      * Creates a {@code PipedInputStream} so
   131      * that it is not yet {@linkplain #connect(java.io.PipedOutputStream)
   131      * that it is not yet {@linkplain #connect(java.io.PipedOutputStream)
   132      * connected}.
   132      * connected}.
   133      * It must be {@linkplain java.io.PipedOutputStream#connect(
   133      * It must be {@linkplain java.io.PipedOutputStream#connect(
   134      * java.io.PipedInputStream) connected} to a
   134      * java.io.PipedInputStream) connected} to a
   135      * <code>PipedOutputStream</code> before being used.
   135      * {@code PipedOutputStream} before being used.
   136      */
   136      */
   137     public PipedInputStream() {
   137     public PipedInputStream() {
   138         initPipe(DEFAULT_PIPE_SIZE);
   138         initPipe(DEFAULT_PIPE_SIZE);
   139     }
   139     }
   140 
   140 
   141     /**
   141     /**
   142      * Creates a <code>PipedInputStream</code> so that it is not yet
   142      * Creates a {@code PipedInputStream} so that it is not yet
   143      * {@linkplain #connect(java.io.PipedOutputStream) connected} and
   143      * {@linkplain #connect(java.io.PipedOutputStream) connected} and
   144      * uses the specified pipe size for the pipe's buffer.
   144      * uses the specified pipe size for the pipe's buffer.
   145      * It must be {@linkplain java.io.PipedOutputStream#connect(
   145      * It must be {@linkplain java.io.PipedOutputStream#connect(
   146      * java.io.PipedInputStream)
   146      * java.io.PipedInputStream)
   147      * connected} to a <code>PipedOutputStream</code> before being used.
   147      * connected} to a {@code PipedOutputStream} before being used.
   148      *
   148      *
   149      * @param      pipeSize the size of the pipe's buffer.
   149      * @param      pipeSize the size of the pipe's buffer.
   150      * @throws     IllegalArgumentException if {@code pipeSize <= 0}.
   150      * @throws     IllegalArgumentException if {@code pipeSize <= 0}.
   151      * @since      1.6
   151      * @since      1.6
   152      */
   152      */
   161          buffer = new byte[pipeSize];
   161          buffer = new byte[pipeSize];
   162     }
   162     }
   163 
   163 
   164     /**
   164     /**
   165      * Causes this piped input stream to be connected
   165      * Causes this piped input stream to be connected
   166      * to the piped  output stream <code>src</code>.
   166      * to the piped  output stream {@code src}.
   167      * If this object is already connected to some
   167      * If this object is already connected to some
   168      * other piped output  stream, an <code>IOException</code>
   168      * other piped output  stream, an {@code IOException}
   169      * is thrown.
   169      * is thrown.
   170      * <p>
   170      * <p>
   171      * If <code>src</code> is an
   171      * If {@code src} is an
   172      * unconnected piped output stream and <code>snk</code>
   172      * unconnected piped output stream and {@code snk}
   173      * is an unconnected piped input stream, they
   173      * is an unconnected piped input stream, they
   174      * may be connected by either the call:
   174      * may be connected by either the call:
   175      *
   175      *
   176      * <pre><code>snk.connect(src)</code> </pre>
   176      * <pre>{@code snk.connect(src)} </pre>
   177      * <p>
   177      * <p>
   178      * or the call:
   178      * or the call:
   179      *
   179      *
   180      * <pre><code>src.connect(snk)</code> </pre>
   180      * <pre>{@code src.connect(snk)} </pre>
   181      * <p>
   181      * <p>
   182      * The two calls have the same effect.
   182      * The two calls have the same effect.
   183      *
   183      *
   184      * @param      src   The piped output stream to connect to.
   184      * @param      src   The piped output stream to connect to.
   185      * @throws     IOException  if an I/O error occurs.
   185      * @throws     IOException  if an I/O error occurs.
   190 
   190 
   191     /**
   191     /**
   192      * Receives a byte of data.  This method will block if no input is
   192      * Receives a byte of data.  This method will block if no input is
   193      * available.
   193      * available.
   194      * @param   b the byte being received
   194      * @param   b the byte being received
   195      * @throws  IOException If the pipe is <a href="#BROKEN"> <code>broken</code></a>,
   195      * @throws  IOException If the pipe is <a href="#BROKEN"> {@code broken}</a>,
   196      *          {@link #connect(java.io.PipedOutputStream) unconnected},
   196      *          {@link #connect(java.io.PipedOutputStream) unconnected},
   197      *          closed, or if an I/O error occurs.
   197      *          closed, or if an I/O error occurs.
   198      * @since   1.1
   198      * @since   1.1
   199      */
   199      */
   200     protected synchronized void receive(int b) throws IOException {
   200     protected synchronized void receive(int b) throws IOException {
   286         notifyAll();
   286         notifyAll();
   287     }
   287     }
   288 
   288 
   289     /**
   289     /**
   290      * Reads the next byte of data from this piped input stream. The
   290      * Reads the next byte of data from this piped input stream. The
   291      * value byte is returned as an <code>int</code> in the range
   291      * value byte is returned as an {@code int} in the range
   292      * <code>0</code> to <code>255</code>.
   292      * {@code 0} to {@code 255}.
   293      * This method blocks until input data is available, the end of the
   293      * This method blocks until input data is available, the end of the
   294      * stream is detected, or an exception is thrown.
   294      * stream is detected, or an exception is thrown.
   295      *
   295      *
   296      * @return   the next byte of data, or <code>-1</code> if the end of the
   296      * @return   the next byte of data, or {@code -1} if the end of the
   297      *           stream is reached.
   297      *           stream is reached.
   298      * @throws   IOException  if the pipe is
   298      * @throws   IOException  if the pipe is
   299      *           {@link #connect(java.io.PipedOutputStream) unconnected},
   299      *           {@link #connect(java.io.PipedOutputStream) unconnected},
   300      *           <a href="#BROKEN"> <code>broken</code></a>, closed,
   300      *           <a href="#BROKEN"> {@code broken}</a>, closed,
   301      *           or if an I/O error occurs.
   301      *           or if an I/O error occurs.
   302      */
   302      */
   303     public synchronized int read()  throws IOException {
   303     public synchronized int read()  throws IOException {
   304         if (!connected) {
   304         if (!connected) {
   305             throw new IOException("Pipe not connected");
   305             throw new IOException("Pipe not connected");
   339 
   339 
   340         return ret;
   340         return ret;
   341     }
   341     }
   342 
   342 
   343     /**
   343     /**
   344      * Reads up to <code>len</code> bytes of data from this piped input
   344      * Reads up to {@code len} bytes of data from this piped input
   345      * stream into an array of bytes. Less than <code>len</code> bytes
   345      * stream into an array of bytes. Less than {@code len} bytes
   346      * will be read if the end of the data stream is reached or if
   346      * will be read if the end of the data stream is reached or if
   347      * <code>len</code> exceeds the pipe's buffer size.
   347      * {@code len} exceeds the pipe's buffer size.
   348      * If <code>len </code> is zero, then no bytes are read and 0 is returned;
   348      * If {@code len } is zero, then no bytes are read and 0 is returned;
   349      * otherwise, the method blocks until at least 1 byte of input is
   349      * otherwise, the method blocks until at least 1 byte of input is
   350      * available, end of the stream has been detected, or an exception is
   350      * available, end of the stream has been detected, or an exception is
   351      * thrown.
   351      * thrown.
   352      *
   352      *
   353      * @param      b     the buffer into which the data is read.
   353      * @param      b     the buffer into which the data is read.
   354      * @param      off   the start offset in the destination array <code>b</code>
   354      * @param      off   the start offset in the destination array {@code b}
   355      * @param      len   the maximum number of bytes read.
   355      * @param      len   the maximum number of bytes read.
   356      * @return     the total number of bytes read into the buffer, or
   356      * @return     the total number of bytes read into the buffer, or
   357      *             <code>-1</code> if there is no more data because the end of
   357      *             {@code -1} if there is no more data because the end of
   358      *             the stream has been reached.
   358      *             the stream has been reached.
   359      * @throws     NullPointerException If <code>b</code> is <code>null</code>.
   359      * @throws     NullPointerException If {@code b} is {@code null}.
   360      * @throws     IndexOutOfBoundsException If <code>off</code> is negative,
   360      * @throws     IndexOutOfBoundsException If {@code off} is negative,
   361      *             <code>len</code> is negative, or <code>len</code> is greater than
   361      *             {@code len} is negative, or {@code len} is greater than
   362      *             <code>b.length - off</code>
   362      *             {@code b.length - off}
   363      * @throws     IOException if the pipe is <a href="#BROKEN"> <code>broken</code></a>,
   363      * @throws     IOException if the pipe is <a href="#BROKEN"> {@code broken}</a>,
   364      *           {@link #connect(java.io.PipedOutputStream) unconnected},
   364      *           {@link #connect(java.io.PipedOutputStream) unconnected},
   365      *           closed, or if an I/O error occurs.
   365      *           closed, or if an I/O error occurs.
   366      */
   366      */
   367     public synchronized int read(byte b[], int off, int len)  throws IOException {
   367     public synchronized int read(byte b[], int off, int len)  throws IOException {
   368         if (b == null) {
   368         if (b == null) {
   416      *
   416      *
   417      * @return the number of bytes that can be read from this input stream
   417      * @return the number of bytes that can be read from this input stream
   418      *         without blocking, or {@code 0} if this input stream has been
   418      *         without blocking, or {@code 0} if this input stream has been
   419      *         closed by invoking its {@link #close()} method, or if the pipe
   419      *         closed by invoking its {@link #close()} method, or if the pipe
   420      *         is {@link #connect(java.io.PipedOutputStream) unconnected}, or
   420      *         is {@link #connect(java.io.PipedOutputStream) unconnected}, or
   421      *         <a href="#BROKEN"> <code>broken</code></a>.
   421      *         <a href="#BROKEN"> {@code broken}</a>.
   422      *
   422      *
   423      * @throws IOException  if an I/O error occurs.
   423      * @throws IOException  if an I/O error occurs.
   424      * @since  1.0.2
   424      * @since  1.0.2
   425      */
   425      */
   426     public synchronized int available() throws IOException {
   426     public synchronized int available() throws IOException {