📄 bufferedreader.java
字号:
/* * @(#)BufferedReader.java 1.35 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program 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. * * This program 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 at /legal/license.txt). * * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */package java.io;/** * Read text from a character-input stream, buffering characters so as to * provide for the efficient reading of characters, arrays, and lines. * * <p> The buffer size may be specified, or the default size may be used. The * default is large enough for most purposes. * * <p> In general, each read request made of a Reader causes a corresponding * read request to be made of the underlying character or byte stream. It is * therefore advisable to wrap a BufferedReader around any Reader whose read() * operations may be costly, such as FileReaders and InputStreamReaders. For * example, * * <pre> * BufferedReader in * = new BufferedReader(new FileReader("foo.in")); * </pre> * * will buffer the input from the specified file. Without buffering, each * invocation of read() or readLine() could cause bytes to be read from the * file, converted into characters, and then returned, which can be very * inefficient. * * <p> Programs that use DataInputStreams for textual input can be localized by * replacing each DataInputStream with an appropriate BufferedReader. * * @see FileReader * @see InputStreamReader * * @version 1.29 10/10/01 * @author Mark Reinhold * @since JDK1.1 */public class BufferedReader extends Reader { private Reader in; private char cb[]; private int nChars, nextChar; private static final int INVALIDATED = -2; private static final int UNMARKED = -1; private int markedChar = UNMARKED; private int readAheadLimit = 0; /* Valid only when markedChar > 0 */ /** If the next character is a line feed, skip it */ private boolean skipLF = false; /** The skipLF flag when the mark was set */ private boolean markedSkipLF = false; private static int defaultCharBufferSize = 8192; private static int defaultExpectedLineLength = 80; /** * Create a buffering character-input stream that uses an input buffer of * the specified size. * * @param in A Reader * @param sz Input-buffer size * * @exception IllegalArgumentException If sz is <= 0 */ public BufferedReader(Reader in, int sz) { super(in); if (sz <= 0) throw new IllegalArgumentException("Buffer size <= 0"); this.in = in; cb = new char[sz]; nextChar = nChars = 0; } /** * Create a buffering character-input stream that uses a default-sized * input buffer. * * @param in A Reader */ public BufferedReader(Reader in) { this(in, defaultCharBufferSize); } /** Check to make sure that the stream has not been closed */ private void ensureOpen() throws IOException { if (in == null) throw new IOException("Stream closed"); } /** * Fill the input buffer, taking the mark into account if it is valid. */ private void fill() throws IOException { int dst; if (markedChar <= UNMARKED) { /* No mark */ dst = 0; } else { /* Marked */ int delta = nextChar - markedChar; if (delta >= readAheadLimit) { /* Gone past read-ahead limit: Invalidate mark */ markedChar = INVALIDATED; readAheadLimit = 0; dst = 0; } else { if (readAheadLimit <= cb.length) { /* Shuffle in the current buffer */ System.arraycopy(cb, markedChar, cb, 0, delta); markedChar = 0; dst = delta; } else { /* Reallocate buffer to accomodate read-ahead limit */ char ncb[] = new char[readAheadLimit]; System.arraycopy(cb, markedChar, ncb, 0, delta); cb = ncb; markedChar = 0; dst = delta; } nextChar = nChars = delta; } } int n; do { n = in.read(cb, dst, cb.length - dst); } while (n == 0); if (n > 0) { nChars = dst + n; nextChar = dst; } } /** * Read a single character. * * @return The character read, as an integer in the range * 0 to 65535 (<tt>0x00-0xffff</tt>), or -1 if the * end of the stream has been reached * @exception IOException If an I/O error occurs */ public int read() throws IOException { synchronized (lock) { ensureOpen(); for (;;) { if (nextChar >= nChars) { fill(); if (nextChar >= nChars) return -1; } if (skipLF) { skipLF = false; if (cb[nextChar] == '\n') { nextChar++; continue; } } return cb[nextChar++]; } } } /** * Read characters into a portion of an array, reading from the underlying * stream if necessary. */ private int read1(char[] cbuf, int off, int len) throws IOException { if (nextChar >= nChars) { /* If the requested length is at least as large as the buffer, and if there is no mark/reset activity, and if line feeds are not being skipped, do not bother to copy the characters into the local buffer. In this way buffered streams will cascade harmlessly. */ if (len >= cb.length && markedChar <= UNMARKED && !skipLF) { return in.read(cbuf, off, len); } fill(); } if (nextChar >= nChars) return -1; if (skipLF) { skipLF = false; if (cb[nextChar] == '\n') { nextChar++; if (nextChar >= nChars) fill(); if (nextChar >= nChars) return -1; } } int n = Math.min(len, nChars - nextChar); System.arraycopy(cb, nextChar, cbuf, off, n); nextChar += n; return n; } /** * Read characters into a portion of an array. * * <p> This method implements the general contract of the corresponding * <code>{@link Reader#read(char[], int, int) read}</code> method of the * <code>{@link Reader}</code> class. As an additional convenience, it * attempts to read as many characters as possible by repeatedly invoking * the <code>read</code> method of the underlying stream. This iterated * <code>read</code> continues until one of the following conditions becomes * true: <ul> * * <li> The specified number of characters have been read, * * <li> The <code>read</code> method of the underlying stream returns * <code>-1</code>, indicating end-of-file, or * * <li> The <code>ready</code> method of the underlying stream * returns <code>false</code>, indicating that further input requests * would block. * * </ul> If the first <code>read</code> on the underlying stream returns * <code>-1</code> to indicate end-of-file then this method returns * <code>-1</code>. Otherwise this method returns the number of characters * actually read. * * <p> Subclasses of this class are encouraged, but not required, to * attempt to read as many characters as possible in the same fashion. * * <p> Ordinarily this method takes characters from this stream's character * buffer, filling it from the underlying stream as necessary. If, * however, the buffer is empty, the mark is not valid, and the requested * length is at least as large as the buffer, then this method will read * characters directly from the underlying stream into the given array. * Thus redundant <code>BufferedReader</code>s will not copy data * unnecessarily. * * @param cbuf Destination buffer * @param off Offset at which to start storing characters * @param len Maximum number of characters to read *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -