Source Home >> Java Source 1.6.0 >> java.io.BufferedReader V 0.09
  • 001/*
  • 002 * @(#)BufferedReader.java 1.37 06/03/15
  • 003 *
  • 004 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
  • 005 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  • 006 */
  • 007
  • 008package java.io;
  • 009
  • 010
  • 011/**
  • 012 * Reads text from a character-input stream, buffering characters so as to
  • 013 * provide for the efficient reading of characters, arrays, and lines.
  • 014 *
  • 015 * <p> The buffer size may be specified, or the default size may be used. The
  • 016 * default is large enough for most purposes.
  • 017 *
  • 018 * <p> In general, each read request made of a Reader causes a corresponding
  • 019 * read request to be made of the underlying character or byte stream. It is
  • 020 * therefore advisable to wrap a BufferedReader around any Reader whose read()
  • 021 * operations may be costly, such as FileReaders and InputStreamReaders. For
  • 022 * example,
  • 023 *
  • 024 * <pre>
  • 025 * BufferedReader in
  • 026 * = new BufferedReader(new FileReader("foo.in"));
  • 027 * </pre>
  • 028 *
  • 029 * will buffer the input from the specified file. Without buffering, each
  • 030 * invocation of read() or readLine() could cause bytes to be read from the
  • 031 * file, converted into characters, and then returned, which can be very
  • 032 * inefficient.
  • 033 *
  • 034 * <p> Programs that use DataInputStreams for textual input can be localized by
  • 035 * replacing each DataInputStream with an appropriate BufferedReader.
  • 036 *
  • 037 * @see FileReader
  • 038 * @see InputStreamReader
  • 039 *
  • 040 * @version 1.37, 06/03/15
  • 041 * @author Mark Reinhold
  • 042 * @since JDK1.1
  • 043 */
  • 044
  • 045public class BufferedReader extends Reader {
  • 046
  • 047 private Reader in;
  • 048
  • 049 private char cb[];
  • 050 private int nChars, nextChar;
  • 051
  • 052 private static final int INVALIDATED = -2;
  • 053 private static final int UNMARKED = -1;
  • 054 private int markedChar = UNMARKED;
  • 055 private int readAheadLimit = 0; /* Valid only when markedChar > 0 */
  • 056
  • 057 /** If the next character is a line feed, skip it */
  • 058 private boolean skipLF = false;
  • 059
  • 060 /** The skipLF flag when the mark was set */
  • 061 private boolean markedSkipLF = false;
  • 062
  • 063 private static int defaultCharBufferSize = 8192;
  • 064 private static int defaultExpectedLineLength = 80;
  • 065
  • 066 /**
  • 067 * Creates a buffering character-input stream that uses an input buffer of
  • 068 * the specified size.
  • 069 *
  • 070 * @param in A Reader
  • 071 * @param sz Input-buffer size
  • 072 *
  • 073 * @exception IllegalArgumentException If sz is <= 0
  • 074 */
  • 075 public BufferedReader(Reader in, int sz) {
  • 076 super(in);
  • 077 if (sz <= 0)
  • 078 throw new IllegalArgumentException("Buffer size <= 0");
  • 079 this.in = in;
  • 080 cb = new char[sz];
  • 081 nextChar = nChars = 0;
  • 082 }
  • 083
  • 084 /**
  • 085 * Creates a buffering character-input stream that uses a default-sized
  • 086 * input buffer.
  • 087 *
  • 088 * @param in A Reader
  • 089 */
  • 090 public BufferedReader(Reader in) {
  • 091 this(in, defaultCharBufferSize);
  • 092 }
  • 093
  • 094 /** Checks to make sure that the stream has not been closed */
  • 095 private void ensureOpen() throws IOException {
  • 096 if (in == null)
  • 097 throw new IOException("Stream closed");
  • 098 }
  • 099
  • 100 /**
  • 101 * Fills the input buffer, taking the mark into account if it is valid.
  • 102 */
  • 103 private void fill() throws IOException {
  • 104 int dst;
  • 105 if (markedChar <= UNMARKED) {
  • 106 /* No mark */
  • 107 dst = 0;
  • 108 } else {
  • 109 /* Marked */
  • 110 int delta = nextChar - markedChar;
  • 111 if (delta >= readAheadLimit) {
  • 112 /* Gone past read-ahead limit: Invalidate mark */
  • 113 markedChar = INVALIDATED;
  • 114 readAheadLimit = 0;
  • 115 dst = 0;
  • 116 } else {
  • 117 if (readAheadLimit <= cb.length) {
  • 118 /* Shuffle in the current buffer */
  • 119 System.arraycopy(cb, markedChar, cb, 0, delta);
  • 120 markedChar = 0;
  • 121 dst = delta;
  • 122 } else {
  • 123 /* Reallocate buffer to accommodate read-ahead limit */
  • 124 char ncb[] = new char[readAheadLimit];
  • 125 System.arraycopy(cb, markedChar, ncb, 0, delta);
  • 126 cb = ncb;
  • 127 markedChar = 0;
  • 128 dst = delta;
  • 129 }
  • 130 nextChar = nChars = delta;
  • 131 }
  • 132 }
  • 133
  • 134 int n;
  • 135 do {
  • 136 n = in.read(cb, dst, cb.length - dst);
  • 137 } while (n == 0);
  • 138 if (n > 0) {
  • 139 nChars = dst + n;
  • 140 nextChar = dst;
  • 141 }
  • 142 }
  • 143
  • 144 /**
  • 145 * Reads a single character.
  • 146 *
  • 147 * @return The character read, as an integer in the range
  • 148 * 0 to 65535 (<tt>0x00-0xffff</tt>), or -1 if the
  • 149 * end of the stream has been reached
  • 150 * @exception IOException If an I/O error occurs
  • 151 */
  • 152 public int read() throws IOException {
  • 153 synchronized (lock) {
  • 154 ensureOpen();
  • 155 for (;;) {
  • 156 if (nextChar >= nChars) {
  • 157 fill();
  • 158 if (nextChar >= nChars)
  • 159 return -1;
  • 160 }
  • 161 if (skipLF) {
  • 162 skipLF = false;
  • 163 if (cb[nextChar] == '\n') {
  • 164 nextChar++;
  • 165 continue;
  • 166 }
  • 167 }
  • 168 return cb[nextChar++];
  • 169 }
  • 170 }
  • 171 }
  • 172
  • 173 /**
  • 174 * Reads characters into a portion of an array, reading from the underlying
  • 175 * stream if necessary.
  • 176 */
  • 177 private int read1(char[] cbuf, int off, int len) throws IOException {
  • 178 if (nextChar >= nChars) {
  • 179 /* If the requested length is at least as large as the buffer, and
  • 180 if there is no mark/reset activity, and if line feeds are not
  • 181 being skipped, do not bother to copy the characters into the
  • 182 local buffer. In this way buffered streams will cascade
  • 183 harmlessly. */
  • 184 if (len >= cb.length && markedChar <= UNMARKED && !skipLF) {
  • 185 return in.read(cbuf, off, len);
  • 186 }
  • 187 fill();
  • 188 }
  • 189 if (nextChar >= nChars) return -1;
  • 190 if (skipLF) {
  • 191 skipLF = false;
  • 192 if (cb[nextChar] == '\n') {
  • 193 nextChar++;
  • 194 if (nextChar >= nChars)
  • 195 fill();
  • 196 if (nextChar >= nChars)
  • 197 return -1;
  • 198 }
  • 199 }
  • 200 int n = Math.min(len, nChars - nextChar);
  • 201 System.arraycopy(cb, nextChar, cbuf, off, n);
  • 202 nextChar += n;
  • 203 return n;
  • 204 }
  • 205
  • 206 /**
  • 207 * Reads characters into a portion of an array.
  • 208 *
  • 209 * <p> This method implements the general contract of the corresponding
  • 210 * <code>{@link Reader#read(char[], int, int) read}</code> method of the
  • 211 * <code>{@link Reader}</code> class. As an additional convenience, it
  • 212 * attempts to read as many characters as possible by repeatedly invoking
  • 213 * the <code>read</code> method of the underlying stream. This iterated
  • 214 * <code>read</code> continues until one of the following conditions becomes
  • 215 * true: <ul>
  • 216 *
  • 217 * <li> The specified number of characters have been read,
  • 218 *
  • 219 * <li> The <code>read</code> method of the underlying stream returns
  • 220 * <code>-1</code>, indicating end-of-file, or
  • 221 *
  • 222 * <li> The <code>ready</code> method of the underlying stream
  • 223 * returns <code>false</code>, indicating that further input requests
  • 224 * would block.
  • 225 *
  • 226 * </ul> If the first <code>read</code> on the underlying stream returns
  • 227 * <code>-1</code> to indicate end-of-file then this method returns
  • 228 * <code>-1</code>. Otherwise this method returns the number of characters
  • 229 * actually read.
  • 230 *
  • 231 * <p> Subclasses of this class are encouraged, but not required, to
  • 232 * attempt to read as many characters as possible in the same fashion.
  • 233 *
  • 234 * <p> Ordinarily this method takes characters from this stream's character
  • 235 * buffer, filling it from the underlying stream as necessary. If,
  • 236 * however, the buffer is empty, the mark is not valid, and the requested
  • 237 * length is at least as large as the buffer, then this method will read
  • 238 * characters directly from the underlying stream into the given array.
  • 239 * Thus redundant <code>BufferedReader</code>s will not copy data
  • 240 * unnecessarily.
  • 241 *
  • 242 * @param cbuf Destination buffer
  • 243 * @param off Offset at which to start storing characters
  • 244 * @param len Maximum number of characters to read
  • 245 *
  • 246 * @return The number of characters read, or -1 if the end of the
  • 247 * stream has been reached
  • 248 *
  • 249 * @exception IOException If an I/O error occurs
  • 250 */
  • 251 public int read(char cbuf[], int off, int len) throws IOException {
  • 252 synchronized (lock) {
  • 253 ensureOpen();
  • 254 if ((off < 0) || (off > cbuf.length) || (len < 0) ||
  • 255 ((off + len) > cbuf.length) || ((off + len) < 0)) {
  • 256 throw new IndexOutOfBoundsException();
  • 257 } else if (len == 0) {
  • 258 return 0;
  • 259 }
  • 260
  • 261 int n = read1(cbuf, off, len);
  • 262 if (n <= 0) return n;
  • 263 while ((n < len) && in.ready()) {
  • 264 int n1 = read1(cbuf, off + n, len - n);
  • 265 if (n1 <= 0) break;
  • 266 n += n1;
  • 267 }
  • 268 return n;
  • 269 }
  • 270 }
  • 271
  • 272 /**
  • 273 * Reads a line of text. A line is considered to be terminated by any one
  • 274 * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
  • 275 * followed immediately by a linefeed.
  • 276 *
  • 277 * @param ignoreLF If true, the next '\n' will be skipped
  • 278 *
  • 279 * @return A String containing the contents of the line, not including
  • 280 * any line-termination characters, or null if the end of the
  • 281 * stream has been reached
  • 282 *
  • 283 * @see java.io.LineNumberReader#readLine()
  • 284 *
  • 285 * @exception IOException If an I/O error occurs
  • 286 */
  • 287 String readLine(boolean ignoreLF) throws IOException {
  • 288 StringBuffer s = null;
  • 289 int startChar;
  • 290
  • 291 synchronized (lock) {
  • 292 ensureOpen();
  • 293 boolean omitLF = ignoreLF || skipLF;
  • 294
  • 295 bufferLoop:
  • 296 for (;;) {
  • 297
  • 298 if (nextChar >= nChars)
  • 299 fill();
  • 300 if (nextChar >= nChars) { /* EOF */
  • 301 if (s != null && s.length() > 0)
  • 302 return s.toString();
  • 303 else
  • 304 return null;
  • 305 }
  • 306 boolean eol = false;
  • 307 char c = 0;
  • 308 int i;
  • 309
  • 310 /* Skip a leftover '\n', if necessary */
  • 311 if (omitLF && (cb[nextChar] == '\n'))
  • 312 nextChar++;
  • 313 skipLF = false;
  • 314 omitLF = false;
  • 315
  • 316 charLoop:
  • 317 for (i = nextChar; i < nChars; i++) {
  • 318 c = cb[i];
  • 319 if ((c == '\n') || (c == '\r')) {
  • 320 eol = true;
  • 321 break charLoop;
  • 322 }
  • 323 }
  • 324
  • 325 startChar = nextChar;
  • 326 nextChar = i;
  • 327
  • 328 if (eol) {
  • 329 String str;
  • 330 if (s == null) {
  • 331 str = new String(cb, startChar, i - startChar);
  • 332 } else {
  • 333 s.append(cb, startChar, i - startChar);
  • 334 str = s.toString();
  • 335 }
  • 336 nextChar++;
  • 337 if (c == '\r') {
  • 338 skipLF = true;
  • 339 }
  • 340 return str;
  • 341 }
  • 342
  • 343 if (s == null)
  • 344 s = new StringBuffer(defaultExpectedLineLength);
  • 345 s.append(cb, startChar, i - startChar);
  • 346 }
  • 347 }
  • 348 }
  • 349
  • 350 /**
  • 351 * Reads a line of text. A line is considered to be terminated by any one
  • 352 * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
  • 353 * followed immediately by a linefeed.
  • 354 *
  • 355 * @return A String containing the contents of the line, not including
  • 356 * any line-termination characters, or null if the end of the
  • 357 * stream has been reached
  • 358 *
  • 359 * @exception IOException If an I/O error occurs
  • 360 */
  • 361 public String readLine() throws IOException {
  • 362 return readLine(false);
  • 363 }
  • 364
  • 365 /**
  • 366 * Skips characters.
  • 367 *
  • 368 * @param n The number of characters to skip
  • 369 *
  • 370 * @return The number of characters actually skipped
  • 371 *
  • 372 * @exception IllegalArgumentException If <code>n</code> is negative.
  • 373 * @exception IOException If an I/O error occurs
  • 374 */
  • 375 public long skip(long n) throws IOException {
  • 376 if (n < 0L) {
  • 377 throw new IllegalArgumentException("skip value is negative");
  • 378 }
  • 379 synchronized (lock) {
  • 380 ensureOpen();
  • 381 long r = n;
  • 382 while (r > 0) {
  • 383 if (nextChar >= nChars)
  • 384 fill();
  • 385 if (nextChar >= nChars) /* EOF */
  • 386 break;
  • 387 if (skipLF) {
  • 388 skipLF = false;
  • 389 if (cb[nextChar] == '\n') {
  • 390 nextChar++;
  • 391 }
  • 392 }
  • 393 long d = nChars - nextChar;
  • 394 if (r <= d) {
  • 395 nextChar += r;
  • 396 r = 0;
  • 397 break;
  • 398 }
  • 399 else {
  • 400 r -= d;
  • 401 nextChar = nChars;
  • 402 }
  • 403 }
  • 404 return n - r;
  • 405 }
  • 406 }
  • 407
  • 408 /**
  • 409 * Tells whether this stream is ready to be read. A buffered character
  • 410 * stream is ready if the buffer is not empty, or if the underlying
  • 411 * character stream is ready.
  • 412 *
  • 413 * @exception IOException If an I/O error occurs
  • 414 */
  • 415 public boolean ready() throws IOException {
  • 416 synchronized (lock) {
  • 417 ensureOpen();
  • 418
  • 419 /*
  • 420 * If newline needs to be skipped and the next char to be read
  • 421 * is a newline character, then just skip it right away.
  • 422 */
  • 423 if (skipLF) {
  • 424 /* Note that in.ready() will return true if and only if the next
  • 425 * read on the stream will not block.
  • 426 */
  • 427 if (nextChar >= nChars && in.ready()) {
  • 428 fill();
  • 429 }
  • 430 if (nextChar < nChars) {
  • 431 if (cb[nextChar] == '\n')
  • 432 nextChar++;
  • 433 skipLF = false;
  • 434 }
  • 435 }
  • 436 return (nextChar < nChars) || in.ready();
  • 437 }
  • 438 }
  • 439
  • 440 /**
  • 441 * Tells whether this stream supports the mark() operation, which it does.
  • 442 */
  • 443 public boolean markSupported() {
  • 444 return true;
  • 445 }
  • 446
  • 447 /**
  • 448 * Marks the present position in the stream. Subsequent calls to reset()
  • 449 * will attempt to reposition the stream to this point.
  • 450 *
  • 451 * @param readAheadLimit Limit on the number of characters that may be
  • 452 * read while still preserving the mark. An attempt
  • 453 * to reset the stream after reading characters
  • 454 * up to this limit or beyond may fail.
  • 455 * A limit value larger than the size of the input
  • 456 * buffer will cause a new buffer to be allocated
  • 457 * whose size is no smaller than limit.
  • 458 * Therefore large values should be used with care.
  • 459 *
  • 460 * @exception IllegalArgumentException If readAheadLimit is < 0
  • 461 * @exception IOException If an I/O error occurs
  • 462 */
  • 463 public void mark(int readAheadLimit) throws IOException {
  • 464 if (readAheadLimit < 0) {
  • 465 throw new IllegalArgumentException("Read-ahead limit < 0");
  • 466 }
  • 467 synchronized (lock) {
  • 468 ensureOpen();
  • 469 this.readAheadLimit = readAheadLimit;
  • 470 markedChar = nextChar;
  • 471 markedSkipLF = skipLF;
  • 472 }
  • 473 }
  • 474
  • 475 /**
  • 476 * Resets the stream to the most recent mark.
  • 477 *
  • 478 * @exception IOException If the stream has never been marked,
  • 479 * or if the mark has been invalidated
  • 480 */
  • 481 public void reset() throws IOException {
  • 482 synchronized (lock) {
  • 483 ensureOpen();
  • 484 if (markedChar < 0)
  • 485 throw new IOException((markedChar == INVALIDATED)
  • 486 ? "Mark invalid"
  • 487 : "Stream not marked");
  • 488 nextChar = markedChar;
  • 489 skipLF = markedSkipLF;
  • 490 }
  • 491 }
  • 492
  • 493 public void close() throws IOException {
  • 494 synchronized (lock) {
  • 495 if (in == null)
  • 496 return;
  • 497 in.close();
  • 498 in = null;
  • 499 cb = null;
  • 500 }
  • 501 }
  • 502}

文件:BufferedReader.java
包名:java.io
类名:BufferedReader
继承:Reader
接口: