2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
30 * Reads text from a character-input stream, buffering characters so as to
31 * provide for the efficient reading of characters, arrays, and lines.
33 * <p> The buffer size may be specified, or the default size may be used. The
34 * default is large enough for most purposes.
36 * <p> In general, each read request made of a Reader causes a corresponding
37 * read request to be made of the underlying character or byte stream. It is
38 * therefore advisable to wrap a BufferedReader around any Reader whose read()
39 * operations may be costly, such as FileReaders and InputStreamReaders. For
44 * = new BufferedReader(new FileReader("foo.in"));
47 * will buffer the input from the specified file. Without buffering, each
48 * invocation of read() or readLine() could cause bytes to be read from the
49 * file, converted into characters, and then returned, which can be very
52 * <p> Programs that use DataInputStreams for textual input can be localized by
53 * replacing each DataInputStream with an appropriate BufferedReader.
56 * @see InputStreamReader
57 * @see java.nio.file.Files#newBufferedReader
59 * @author Mark Reinhold
63 public class BufferedReader extends Reader {
68 private int nChars, nextChar;
70 private static final int INVALIDATED = -2;
71 private static final int UNMARKED = -1;
72 private int markedChar = UNMARKED;
73 private int readAheadLimit = 0; /* Valid only when markedChar > 0 */
75 /** If the next character is a line feed, skip it */
76 private boolean skipLF = false;
78 /** The skipLF flag when the mark was set */
79 private boolean markedSkipLF = false;
81 private static int defaultCharBufferSize = 8192;
82 private static int defaultExpectedLineLength = 80;
85 * Creates a buffering character-input stream that uses an input buffer of
89 * @param sz Input-buffer size
91 * @exception IllegalArgumentException If sz is <= 0
93 public BufferedReader(Reader in, int sz) {
96 throw new IllegalArgumentException("Buffer size <= 0");
99 nextChar = nChars = 0;
103 * Creates a buffering character-input stream that uses a default-sized
108 public BufferedReader(Reader in) {
109 this(in, defaultCharBufferSize);
112 /** Checks to make sure that the stream has not been closed */
113 private void ensureOpen() throws IOException {
115 throw new IOException("Stream closed");
119 * Fills the input buffer, taking the mark into account if it is valid.
121 private void fill() throws IOException {
123 if (markedChar <= UNMARKED) {
128 int delta = nextChar - markedChar;
129 if (delta >= readAheadLimit) {
130 /* Gone past read-ahead limit: Invalidate mark */
131 markedChar = INVALIDATED;
135 if (readAheadLimit <= cb.length) {
136 /* Shuffle in the current buffer */
137 System.arraycopy(cb, markedChar, cb, 0, delta);
141 /* Reallocate buffer to accommodate read-ahead limit */
142 char ncb[] = new char[readAheadLimit];
143 System.arraycopy(cb, markedChar, ncb, 0, delta);
148 nextChar = nChars = delta;
154 n = in.read(cb, dst, cb.length - dst);
163 * Reads a single character.
165 * @return The character read, as an integer in the range
166 * 0 to 65535 (<tt>0x00-0xffff</tt>), or -1 if the
167 * end of the stream has been reached
168 * @exception IOException If an I/O error occurs
170 public int read() throws IOException {
171 synchronized (lock) {
174 if (nextChar >= nChars) {
176 if (nextChar >= nChars)
181 if (cb[nextChar] == '\n') {
186 return cb[nextChar++];
192 * Reads characters into a portion of an array, reading from the underlying
193 * stream if necessary.
195 private int read1(char[] cbuf, int off, int len) throws IOException {
196 if (nextChar >= nChars) {
197 /* If the requested length is at least as large as the buffer, and
198 if there is no mark/reset activity, and if line feeds are not
199 being skipped, do not bother to copy the characters into the
200 local buffer. In this way buffered streams will cascade
202 if (len >= cb.length && markedChar <= UNMARKED && !skipLF) {
203 return in.read(cbuf, off, len);
207 if (nextChar >= nChars) return -1;
210 if (cb[nextChar] == '\n') {
212 if (nextChar >= nChars)
214 if (nextChar >= nChars)
218 int n = Math.min(len, nChars - nextChar);
219 System.arraycopy(cb, nextChar, cbuf, off, n);
225 * Reads characters into a portion of an array.
227 * <p> This method implements the general contract of the corresponding
228 * <code>{@link Reader#read(char[], int, int) read}</code> method of the
229 * <code>{@link Reader}</code> class. As an additional convenience, it
230 * attempts to read as many characters as possible by repeatedly invoking
231 * the <code>read</code> method of the underlying stream. This iterated
232 * <code>read</code> continues until one of the following conditions becomes
235 * <li> The specified number of characters have been read,
237 * <li> The <code>read</code> method of the underlying stream returns
238 * <code>-1</code>, indicating end-of-file, or
240 * <li> The <code>ready</code> method of the underlying stream
241 * returns <code>false</code>, indicating that further input requests
244 * </ul> If the first <code>read</code> on the underlying stream returns
245 * <code>-1</code> to indicate end-of-file then this method returns
246 * <code>-1</code>. Otherwise this method returns the number of characters
249 * <p> Subclasses of this class are encouraged, but not required, to
250 * attempt to read as many characters as possible in the same fashion.
252 * <p> Ordinarily this method takes characters from this stream's character
253 * buffer, filling it from the underlying stream as necessary. If,
254 * however, the buffer is empty, the mark is not valid, and the requested
255 * length is at least as large as the buffer, then this method will read
256 * characters directly from the underlying stream into the given array.
257 * Thus redundant <code>BufferedReader</code>s will not copy data
260 * @param cbuf Destination buffer
261 * @param off Offset at which to start storing characters
262 * @param len Maximum number of characters to read
264 * @return The number of characters read, or -1 if the end of the
265 * stream has been reached
267 * @exception IOException If an I/O error occurs
269 public int read(char cbuf[], int off, int len) throws IOException {
270 synchronized (lock) {
272 if ((off < 0) || (off > cbuf.length) || (len < 0) ||
273 ((off + len) > cbuf.length) || ((off + len) < 0)) {
274 throw new IndexOutOfBoundsException();
275 } else if (len == 0) {
279 int n = read1(cbuf, off, len);
280 if (n <= 0) return n;
281 while ((n < len) && in.ready()) {
282 int n1 = read1(cbuf, off + n, len - n);
291 * Reads a line of text. A line is considered to be terminated by any one
292 * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
293 * followed immediately by a linefeed.
295 * @param ignoreLF If true, the next '\n' will be skipped
297 * @return A String containing the contents of the line, not including
298 * any line-termination characters, or null if the end of the
299 * stream has been reached
301 * @see java.io.LineNumberReader#readLine()
303 * @exception IOException If an I/O error occurs
305 String readLine(boolean ignoreLF) throws IOException {
306 StringBuffer s = null;
309 synchronized (lock) {
311 boolean omitLF = ignoreLF || skipLF;
316 if (nextChar >= nChars)
318 if (nextChar >= nChars) { /* EOF */
319 if (s != null && s.length() > 0)
328 /* Skip a leftover '\n', if necessary */
329 if (omitLF && (cb[nextChar] == '\n'))
335 for (i = nextChar; i < nChars; i++) {
337 if ((c == '\n') || (c == '\r')) {
343 startChar = nextChar;
349 str = new String(cb, startChar, i - startChar);
351 s.append(cb, startChar, i - startChar);
362 s = new StringBuffer(defaultExpectedLineLength);
363 s.append(cb, startChar, i - startChar);
369 * Reads a line of text. A line is considered to be terminated by any one
370 * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
371 * followed immediately by a linefeed.
373 * @return A String containing the contents of the line, not including
374 * any line-termination characters, or null if the end of the
375 * stream has been reached
377 * @exception IOException If an I/O error occurs
379 * @see java.nio.file.Files#readAllLines
381 public String readLine() throws IOException {
382 return readLine(false);
388 * @param n The number of characters to skip
390 * @return The number of characters actually skipped
392 * @exception IllegalArgumentException If <code>n</code> is negative.
393 * @exception IOException If an I/O error occurs
395 public long skip(long n) throws IOException {
397 throw new IllegalArgumentException("skip value is negative");
399 synchronized (lock) {
403 if (nextChar >= nChars)
405 if (nextChar >= nChars) /* EOF */
409 if (cb[nextChar] == '\n') {
413 long d = nChars - nextChar;
429 * Tells whether this stream is ready to be read. A buffered character
430 * stream is ready if the buffer is not empty, or if the underlying
431 * character stream is ready.
433 * @exception IOException If an I/O error occurs
435 public boolean ready() throws IOException {
436 synchronized (lock) {
440 * If newline needs to be skipped and the next char to be read
441 * is a newline character, then just skip it right away.
444 /* Note that in.ready() will return true if and only if the next
445 * read on the stream will not block.
447 if (nextChar >= nChars && in.ready()) {
450 if (nextChar < nChars) {
451 if (cb[nextChar] == '\n')
456 return (nextChar < nChars) || in.ready();
461 * Tells whether this stream supports the mark() operation, which it does.
463 public boolean markSupported() {
468 * Marks the present position in the stream. Subsequent calls to reset()
469 * will attempt to reposition the stream to this point.
471 * @param readAheadLimit Limit on the number of characters that may be
472 * read while still preserving the mark. An attempt
473 * to reset the stream after reading characters
474 * up to this limit or beyond may fail.
475 * A limit value larger than the size of the input
476 * buffer will cause a new buffer to be allocated
477 * whose size is no smaller than limit.
478 * Therefore large values should be used with care.
480 * @exception IllegalArgumentException If readAheadLimit is < 0
481 * @exception IOException If an I/O error occurs
483 public void mark(int readAheadLimit) throws IOException {
484 if (readAheadLimit < 0) {
485 throw new IllegalArgumentException("Read-ahead limit < 0");
487 synchronized (lock) {
489 this.readAheadLimit = readAheadLimit;
490 markedChar = nextChar;
491 markedSkipLF = skipLF;
496 * Resets the stream to the most recent mark.
498 * @exception IOException If the stream has never been marked,
499 * or if the mark has been invalidated
501 public void reset() throws IOException {
502 synchronized (lock) {
505 throw new IOException((markedChar == INVALIDATED)
507 : "Stream not marked");
508 nextChar = markedChar;
509 skipLF = markedSkipLF;
513 public void close() throws IOException {
514 synchronized (lock) {