home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / io / BufferedWriter.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  7.2 KB  |  258 lines  |  [TEXT/CWIE]

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