/* * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
package java.io;
import java.util.Objects;
/** * Piped character-input streams. * * @author Mark Reinhold * @since 1.1
*/
/* REMIND: identification of the read and write sides needs to be more sophisticated. Either using thread groups (but what about pipes within a thread?) or using finalization (but it may be a
long time until the next GC). */ Thread readSide; Thread writeSide;
/** * The size of the pipe's circular input buffer.
*/ privatestaticfinalint DEFAULT_PIPE_SIZE = 1024;
/** * The circular buffer into which incoming data is placed.
*/ char buffer[];
/** * The index of the position in the circular buffer at which the * next character of data will be stored when received from the connected * piped writer. {@code in < 0} implies the buffer is empty, * {@code in == out} implies the buffer is full
*/ int in = -1;
/** * The index of the position in the circular buffer at which the next * character of data will be read by this piped reader.
*/ int out = 0;
/** * Creates a {@code PipedReader} so * that it is connected to the piped writer * {@code src}. Data written to {@code src} * will then be available as input from this stream. * * @param src the stream to connect to. * @throws IOException if an I/O error occurs.
*/ public PipedReader(PipedWriter src) throws IOException { this(src, DEFAULT_PIPE_SIZE);
}
/** * Creates a {@code PipedReader} so that it is connected * to the piped writer {@code src} and uses the specified * pipe size for the pipe's buffer. Data written to {@code src} * will then be available as input from this stream. * * @param src the stream to connect to. * @param pipeSize the size of the pipe's buffer. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if {@code pipeSize <= 0}. * @since 1.6
*/ public PipedReader(PipedWriter src, int pipeSize) throws IOException {
initPipe(pipeSize);
connect(src);
}
/** * Creates a {@code PipedReader} so * that it is not yet {@linkplain #connect(java.io.PipedWriter) * connected}. It must be {@linkplain java.io.PipedWriter#connect( * java.io.PipedReader) connected} to a {@code PipedWriter} * before being used.
*/ public PipedReader() {
initPipe(DEFAULT_PIPE_SIZE);
}
/** * Creates a {@code PipedReader} so that it is not yet * {@link #connect(java.io.PipedWriter) connected} and uses * the specified pipe size for the pipe's buffer. * It must be {@linkplain java.io.PipedWriter#connect( * java.io.PipedReader) connected} to a {@code PipedWriter} * before being used. * * @param pipeSize the size of the pipe's buffer. * @throws IllegalArgumentException if {@code pipeSize <= 0}. * @since 1.6
*/ public PipedReader(int pipeSize) {
initPipe(pipeSize);
}
/** * Causes this piped reader to be connected * to the piped writer {@code src}. * If this object is already connected to some * other piped writer, an {@code IOException} * is thrown. * <p> * If {@code src} is an * unconnected piped writer and {@code snk} * is an unconnected piped reader, they * may be connected by either the call: * * <pre>{@code snk.connect(src)} </pre> * <p> * or the call: * * <pre>{@code src.connect(snk)} </pre> * <p> * The two calls have the same effect. * * @param src The piped writer to connect to. * @throws IOException if an I/O error occurs.
*/ publicvoid connect(PipedWriter src) throws IOException {
src.connect(this);
}
/** * Receives a char of data. This method will block if no input is * available.
*/ synchronizedvoid receive(int c) throws IOException { if (!connected) { thrownew IOException("Pipe not connected");
} elseif (closedByWriter || closedByReader) { thrownew IOException("Pipe closed");
} elseif (readSide != null && !readSide.isAlive()) { thrownew IOException("Read end dead");
}
writeSide = Thread.currentThread(); while (in == out) { if ((readSide != null) && !readSide.isAlive()) { thrownew IOException("Pipe broken");
} /* full: kick any waiting readers */
notifyAll(); try {
wait(1000);
} catch (InterruptedException ex) { thrownew java.io.InterruptedIOException();
}
} if (in < 0) {
in = 0;
out = 0;
}
buffer[in++] = (char) c; if (in >= buffer.length) {
in = 0;
}
}
/** * Receives data into an array of characters. This method will * block until some input is available.
*/ synchronizedvoid receive(char[] c, int off, int len) throws IOException { while (--len >= 0) {
receive(c[off++]);
}
}
/** * Notifies all waiting threads that the last character of data has been * received.
*/ synchronizedvoid receivedLast() {
closedByWriter = true;
notifyAll();
}
/** * Reads the next character of data from this piped stream. * If no character is available because the end of the stream * has been reached, the value {@code -1} is returned. * This method blocks until input data is available, the end of * the stream is detected, or an exception is thrown. * * @return the next character of data, or {@code -1} if the end of the * stream is reached. * @throws IOException if the pipe is * <a href=PipedInputStream.html#BROKEN> {@code broken}</a>, * {@link #connect(java.io.PipedWriter) unconnected}, closed, * or an I/O error occurs.
*/ publicsynchronizedint read() throws IOException { if (!connected) { thrownew IOException("Pipe not connected");
} elseif (closedByReader) { thrownew IOException("Pipe closed");
} elseif (writeSide != null && !writeSide.isAlive()
&& !closedByWriter && (in < 0)) { thrownew IOException("Write end dead");
}
readSide = Thread.currentThread(); int trials = 2; while (in < 0) { if (closedByWriter) { /* closed by writer, return EOF */ return -1;
} if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) { thrownew IOException("Pipe broken");
} /* might be a writer waiting */
notifyAll(); try {
wait(1000);
} catch (InterruptedException ex) { thrownew java.io.InterruptedIOException();
}
} int ret = buffer[out++]; if (out >= buffer.length) {
out = 0;
} if (in == out) { /* now empty */
in = -1;
} return ret;
}
/** * {@inheritDoc} * * <p> Fewer than {@code len} characters will be read if * {@code len} exceeds the pipe's buffer size. * * @param cbuf {@inheritDoc} * @param off {@inheritDoc} * @param len {@inheritDoc} * * @return {@inheritDoc} * * @throws IndexOutOfBoundsException {@inheritDoc} * @throws IOException if the pipe is * <a href=PipedInputStream.html#BROKEN> {@code broken}</a>, * {@link #connect(java.io.PipedWriter) unconnected}, closed, * or an I/O error occurs.
*/ publicsynchronizedint read(char[] cbuf, int off, int len) throws IOException { if (!connected) { thrownew IOException("Pipe not connected");
} elseif (closedByReader) { thrownew IOException("Pipe closed");
} elseif (writeSide != null && !writeSide.isAlive()
&& !closedByWriter && (in < 0)) { thrownew IOException("Write end dead");
}
/* possibly wait on the first character */ int c = read(); if (c < 0) { return -1;
}
cbuf[off] = (char)c; int rlen = 1; while ((in >= 0) && (--len > 0)) {
cbuf[off + rlen] = buffer[out++];
rlen++; if (out >= buffer.length) {
out = 0;
} if (in == out) { /* now empty */
in = -1;
}
} return rlen;
}
/** * Tell whether this stream is ready to be read. A piped character * stream is ready if the circular buffer is not empty. * * @throws IOException if the pipe is * <a href=PipedInputStream.html#BROKEN> {@code broken}</a>, * {@link #connect(java.io.PipedWriter) unconnected}, or closed.
*/ publicsynchronizedboolean ready() throws IOException { if (!connected) { thrownew IOException("Pipe not connected");
} elseif (closedByReader) { thrownew IOException("Pipe closed");
} elseif (writeSide != null && !writeSide.isAlive()
&& !closedByWriter && (in < 0)) { thrownew IOException("Write end dead");
} if (in < 0) { returnfalse;
} else { returntrue;
}
}
/** * Closes this piped stream and releases any system resources * associated with the stream. * * @throws IOException if an I/O error occurs.
*/ publicvoid close() throws IOException {
in = -1;
closedByReader = true;
}
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.