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

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 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        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.