Source Code Cross Referenced for BufferedReader.java in  » JDK-Core » io-nio » java » io » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. JDK Core
2. JDK Modules
3. JDK Modules com.sun
4. JDK Modules com.sun.java
5. JDK Modules Platform
6. JDK Modules sun
7. Open Source Build
8. Open Source Graphic Library
9. Open Source IDE Eclipse
10. Open Source J2EE
11. Open Source JDBC Driver
12. Open Source Library
13. Open Source Library Database
14. Open Source Net
15. Open Source Script
16. Science
17. Security
18. Sevlet Container
19. SUN GlassFish
20. Swing Library
21. Web Services apache cxf 2.0.1
22. Web Services AXIS2
23. XML
Microsoft Office Word 2007 Tutorial
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java Source Code / Java Documentation » JDK Core » io nio » java.io 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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