Save This Page
Home » openjdk-7 » java » io » [javadoc | source]
    1   /*
    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.
    4    *
    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.
   10    *
   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).
   16    *
   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.
   20    *
   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
   23    * questions.
   24    */
   25   
   26   package java.io;
   27   
   28   
   29   /**
   30    * Writes text to a character-output stream, buffering characters so as to
   31    * provide for the efficient writing of single characters, arrays, and strings.
   32    *
   33    * <p> The buffer size may be specified, or the default size may be accepted.
   34    * The default is large enough for most purposes.
   35    *
   36    * <p> A newLine() method is provided, which uses the platform's own notion of
   37    * line separator as defined by the system property <tt>line.separator</tt>.
   38    * Not all platforms use the newline character ('\n') to terminate lines.
   39    * Calling this method to terminate each output line is therefore preferred to
   40    * writing a newline character directly.
   41    *
   42    * <p> In general, a Writer sends its output immediately to the underlying
   43    * character or byte stream.  Unless prompt output is required, it is advisable
   44    * to wrap a BufferedWriter around any Writer whose write() operations may be
   45    * costly, such as FileWriters and OutputStreamWriters.  For example,
   46    *
   47    * <pre>
   48    * PrintWriter out
   49    *   = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
   50    * </pre>
   51    *
   52    * will buffer the PrintWriter's output to the file.  Without buffering, each
   53    * invocation of a print() method would cause characters to be converted into
   54    * bytes that would then be written immediately to the file, which can be very
   55    * inefficient.
   56    *
   57    * @see PrintWriter
   58    * @see FileWriter
   59    * @see OutputStreamWriter
   60    * @see java.nio.file.Files#newBufferedWriter
   61    *
   62    * @author      Mark Reinhold
   63    * @since       JDK1.1
   64    */
   65   
   66   public class BufferedWriter extends Writer {
   67   
   68       private Writer out;
   69   
   70       private char cb[];
   71       private int nChars, nextChar;
   72   
   73       private static int defaultCharBufferSize = 8192;
   74   
   75       /**
   76        * Line separator string.  This is the value of the line.separator
   77        * property at the moment that the stream was created.
   78        */
   79       private String lineSeparator;
   80   
   81       /**
   82        * Creates a buffered character-output stream that uses a default-sized
   83        * output buffer.
   84        *
   85        * @param  out  A Writer
   86        */
   87       public BufferedWriter(Writer out) {
   88           this(out, defaultCharBufferSize);
   89       }
   90   
   91       /**
   92        * Creates a new buffered character-output stream that uses an output
   93        * buffer of the given size.
   94        *
   95        * @param  out  A Writer
   96        * @param  sz   Output-buffer size, a positive integer
   97        *
   98        * @exception  IllegalArgumentException  If sz is <= 0
   99        */
  100       public BufferedWriter(Writer out, int sz) {
  101           super(out);
  102           if (sz <= 0)
  103               throw new IllegalArgumentException("Buffer size <= 0");
  104           this.out = out;
  105           cb = new char[sz];
  106           nChars = sz;
  107           nextChar = 0;
  108   
  109           lineSeparator = java.security.AccessController.doPrivileged(
  110               new sun.security.action.GetPropertyAction("line.separator"));
  111       }
  112   
  113       /** Checks to make sure that the stream has not been closed */
  114       private void ensureOpen() throws IOException {
  115           if (out == null)
  116               throw new IOException("Stream closed");
  117       }
  118   
  119       /**
  120        * Flushes the output buffer to the underlying character stream, without
  121        * flushing the stream itself.  This method is non-private only so that it
  122        * may be invoked by PrintStream.
  123        */
  124       void flushBuffer() throws IOException {
  125           synchronized (lock) {
  126               ensureOpen();
  127               if (nextChar == 0)
  128                   return;
  129               out.write(cb, 0, nextChar);
  130               nextChar = 0;
  131           }
  132       }
  133   
  134       /**
  135        * Writes a single character.
  136        *
  137        * @exception  IOException  If an I/O error occurs
  138        */
  139       public void write(int c) throws IOException {
  140           synchronized (lock) {
  141               ensureOpen();
  142               if (nextChar >= nChars)
  143                   flushBuffer();
  144               cb[nextChar++] = (char) c;
  145           }
  146       }
  147   
  148       /**
  149        * Our own little min method, to avoid loading java.lang.Math if we've run
  150        * out of file descriptors and we're trying to print a stack trace.
  151        */
  152       private int min(int a, int b) {
  153           if (a < b) return a;
  154           return b;
  155       }
  156   
  157       /**
  158        * Writes a portion of an array of characters.
  159        *
  160        * <p> Ordinarily this method stores characters from the given array into
  161        * this stream's buffer, flushing the buffer to the underlying stream as
  162        * needed.  If the requested length is at least as large as the buffer,
  163        * however, then this method will flush the buffer and write the characters
  164        * directly to the underlying stream.  Thus redundant
  165        * <code>BufferedWriter</code>s will not copy data unnecessarily.
  166        *
  167        * @param  cbuf  A character array
  168        * @param  off   Offset from which to start reading characters
  169        * @param  len   Number of characters to write
  170        *
  171        * @exception  IOException  If an I/O error occurs
  172        */
  173       public void write(char cbuf[], int off, int len) throws IOException {
  174           synchronized (lock) {
  175               ensureOpen();
  176               if ((off < 0) || (off > cbuf.length) || (len < 0) ||
  177                   ((off + len) > cbuf.length) || ((off + len) < 0)) {
  178                   throw new IndexOutOfBoundsException();
  179               } else if (len == 0) {
  180                   return;
  181               }
  182   
  183               if (len >= nChars) {
  184                   /* If the request length exceeds the size of the output buffer,
  185                      flush the buffer and then write the data directly.  In this
  186                      way buffered streams will cascade harmlessly. */
  187                   flushBuffer();
  188                   out.write(cbuf, off, len);
  189                   return;
  190               }
  191   
  192               int b = off, t = off + len;
  193               while (b < t) {
  194                   int d = min(nChars - nextChar, t - b);
  195                   System.arraycopy(cbuf, b, cb, nextChar, d);
  196                   b += d;
  197                   nextChar += d;
  198                   if (nextChar >= nChars)
  199                       flushBuffer();
  200               }
  201           }
  202       }
  203   
  204       /**
  205        * Writes a portion of a String.
  206        *
  207        * <p> If the value of the <tt>len</tt> parameter is negative then no
  208        * characters are written.  This is contrary to the specification of this
  209        * method in the {@linkplain java.io.Writer#write(java.lang.String,int,int)
  210        * superclass}, which requires that an {@link IndexOutOfBoundsException} be
  211        * thrown.
  212        *
  213        * @param  s     String to be written
  214        * @param  off   Offset from which to start reading characters
  215        * @param  len   Number of characters to be written
  216        *
  217        * @exception  IOException  If an I/O error occurs
  218        */
  219       public void write(String s, int off, int len) throws IOException {
  220           synchronized (lock) {
  221               ensureOpen();
  222   
  223               int b = off, t = off + len;
  224               while (b < t) {
  225                   int d = min(nChars - nextChar, t - b);
  226                   s.getChars(b, b + d, cb, nextChar);
  227                   b += d;
  228                   nextChar += d;
  229                   if (nextChar >= nChars)
  230                       flushBuffer();
  231               }
  232           }
  233       }
  234   
  235       /**
  236        * Writes a line separator.  The line separator string is defined by the
  237        * system property <tt>line.separator</tt>, and is not necessarily a single
  238        * newline ('\n') character.
  239        *
  240        * @exception  IOException  If an I/O error occurs
  241        */
  242       public void newLine() throws IOException {
  243           write(lineSeparator);
  244       }
  245   
  246       /**
  247        * Flushes the stream.
  248        *
  249        * @exception  IOException  If an I/O error occurs
  250        */
  251       public void flush() throws IOException {
  252           synchronized (lock) {
  253               flushBuffer();
  254               out.flush();
  255           }
  256       }
  257   
  258       public void close() throws IOException {
  259           synchronized (lock) {
  260               if (out == null) {
  261                   return;
  262               }
  263               try {
  264                   flushBuffer();
  265               } finally {
  266                   out.close();
  267                   out = null;
  268                   cb = null;
  269               }
  270           }
  271       }
  272   }

Save This Page
Home » openjdk-7 » java » io » [javadoc | source]