home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / io / BufferedWriter.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  6.8 KB  |  246 lines

  1. /*
  2.  * @(#)BufferedWriter.java    1.15 98/03/18
  3.  *
  4.  * Copyright 1996, 1997 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.15, 98/03/18
  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.     try {
  98.         java.security.AccessController.beginPrivileged();
  99.         lineSeparator = System.getProperty("line.separator");
  100.     } finally {
  101.         java.security.AccessController.endPrivileged();
  102.     }
  103.     }
  104.  
  105.     /** Check to make sure that the stream has not been closed */
  106.     private void ensureOpen() throws IOException {
  107.     if (out == null)
  108.         throw new IOException("Stream closed");
  109.     }
  110.  
  111.     /**
  112.      * Flush the output buffer to the underlying character stream, without
  113.      * flushing the stream itself.  This method is non-private only so that it
  114.      * may be invoked by PrintStream.
  115.      */
  116.     void flushBuffer() throws IOException {
  117.     synchronized (lock) {
  118.         ensureOpen();
  119.         if (nextChar == 0)
  120.         return;
  121.         out.write(cb, 0, nextChar);
  122.         nextChar = 0;
  123.     }
  124.     }
  125.  
  126.     /**
  127.      * Write a single character.
  128.      *
  129.      * @exception  IOException  If an I/O error occurs
  130.      */
  131.     public void write(int c) throws IOException {
  132.     synchronized (lock) {
  133.         ensureOpen();
  134.         if (nextChar >= nChars)
  135.         flushBuffer();
  136.         cb[nextChar++] = (char) c;
  137.     }
  138.     }
  139.  
  140.     /**
  141.      * Write a portion of an array of characters.
  142.      *
  143.      * <p> Ordinarily this method stores characters from the given array into
  144.      * this stream's buffer, flushing the buffer to the underlying stream as
  145.      * needed.  If the requested length is at least as large as the buffer,
  146.      * however, then this method will flush the buffer and write the characters
  147.      * directly to the underlying stream.  Thus redundant
  148.      * <code>BufferedWriter</code>s will not copy data unnecessarily.
  149.      *
  150.      * @param  cbuf  A character array
  151.      * @param  off   Offset from which to start reading characters
  152.      * @param  len   Number of characters to write
  153.      *
  154.      * @exception  IOException  If an I/O error occurs
  155.      */
  156.     public void write(char cbuf[], int off, int len) throws IOException {
  157.     synchronized (lock) {
  158.         ensureOpen();
  159.  
  160.         if (len >= nChars) {
  161.         /* If the request length exceeds the size of the output buffer,
  162.            flush the buffer and then write the data directly.  In this
  163.            way buffered streams will cascade harmlessly. */
  164.         flushBuffer();
  165.         out.write(cbuf, off, len);
  166.         return;
  167.         }
  168.  
  169.         int b = off, t = off + len;
  170.         while (b < t) {
  171.         int d = Math.min(nChars - nextChar, t - b);
  172.         System.arraycopy(cbuf, b, cb, nextChar, d);
  173.         b += d;
  174.         nextChar += d;
  175.         if (nextChar >= nChars)
  176.             flushBuffer();
  177.         }
  178.     }
  179.     }
  180.  
  181.     /**
  182.      * Write a portion of a String.
  183.      *
  184.      * @param  s     String to be written
  185.      * @param  off   Offset from which to start reading characters
  186.      * @param  len   Number of characters to be written
  187.      *
  188.      * @exception  IOException  If an I/O error occurs
  189.      */
  190.     public void write(String s, int off, int len) throws IOException {
  191.     synchronized (lock) {
  192.         ensureOpen();
  193.  
  194.         int b = off, t = off + len;
  195.         while (b < t) {
  196.         int d = Math.min(nChars - nextChar, t - b);
  197.         s.getChars(b, b + d, cb, nextChar);
  198.         b += d;
  199.         nextChar += d;
  200.         if (nextChar >= nChars)
  201.             flushBuffer();
  202.         }
  203.     }
  204.     }
  205.  
  206.     /**
  207.      * Write a line separator.  The line separator string is defined by the
  208.      * system property <tt>line.separator</tt>, and is not necessarily a single
  209.      * newline ('\n') character.
  210.      *
  211.      * @exception  IOException  If an I/O error occurs
  212.      */
  213.     public void newLine() throws IOException {
  214.     write(lineSeparator);
  215.     }
  216.  
  217.     /**
  218.      * Flush the stream.
  219.      *
  220.      * @exception  IOException  If an I/O error occurs
  221.      */
  222.     public void flush() throws IOException {
  223.     synchronized (lock) {
  224.         flushBuffer();
  225.         out.flush();
  226.     }
  227.     }
  228.  
  229.     /**
  230.      * Close the stream.
  231.      *
  232.      * @exception  IOException  If an I/O error occurs
  233.      */
  234.     public void close() throws IOException {
  235.     synchronized (lock) {
  236.         if (out == null)
  237.         return;
  238.         flushBuffer();
  239.         out.close();
  240.         out = null;
  241.         cb = null;
  242.     }
  243.     }
  244.  
  245. }
  246.