Mega Code Archive

 
Categories / Java / File Input Output
 

Fast BufferedWriter

/*  * @(#)$Id$  *  * Copyright 2006-2008 Makoto YUI  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *     http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  *   * Contributors:  *     Makoto YUI - initial implementation  */ //package xbird.util.io; import java.io.IOException; import java.io.Writer; /**  *   * <DIV lang="en"></DIV>  * <DIV lang="ja"></DIV>  *   * @author Makoto YUI (yuin405+xbird@gmail.com)  */ public final class FastBufferedWriter extends Writer {     private Writer out;     private char cb[];     private int nChars, nextChar;     private static int defaultCharBufferSize = 8192;     /**      * Creates a buffered character-output stream that uses a default-sized      * output buffer.      *      * @param  out  A Writer      */     public FastBufferedWriter(Writer out) {         this(out, defaultCharBufferSize);     }     /**      * Creates a new buffered character-output stream that uses an output      * buffer of the given size.      *      * @param  out  A Writer      * @param  sz   Output-buffer size, a positive integer      *      * @exception  IllegalArgumentException  If sz is <= 0      */     public FastBufferedWriter(Writer out, int sz) {         super(out);         if(sz <= 0)             throw new IllegalArgumentException("Buffer size <= 0");         this.out = out;         cb = new char[sz];         nChars = sz;         nextChar = 0;     }     /**      * Flushes the output buffer to the underlying character stream, without      * flushing the stream itself.  This method is non-private only so that it      * may be invoked by PrintStream.      */     private void flushBuffer() throws IOException {         if(nextChar == 0)             return;         out.write(cb, 0, nextChar);         nextChar = 0;     }     /**      * Writes a single character.      *      * @exception  IOException  If an I/O error occurs      */     public void write(int c) throws IOException {         if(nextChar >= nChars)             flushBuffer();         cb[nextChar++] = (char) c;     }     /**      * Our own little min method, to avoid loading java.lang.Math if we've run      * out of file descriptors and we're trying to print a stack trace.      */     private int min(int a, int b) {         if(a < b)             return a;         return b;     }     /**      * Writes a portion of an array of characters.      *      * <p> Ordinarily this method stores characters from the given array into      * this stream's buffer, flushing the buffer to the underlying stream as      * needed.  If the requested length is at least as large as the buffer,      * however, then this method will flush the buffer and write the characters      * directly to the underlying stream.  Thus redundant      * <code>BufferedWriter</code>s will not copy data unnecessarily.      *      * @param  cbuf  A character array      * @param  off   Offset from which to start reading characters      * @param  len   Number of characters to write      *      * @exception  IOException  If an I/O error occurs      */     public void write(char cbuf[], int off, int len) throws IOException {         if((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length)                 || ((off + len) < 0)) {             throw new IndexOutOfBoundsException();         } else if(len == 0) {             return;         }         if(len >= nChars) {             /* If the request length exceeds the size of the output buffer,              flush the buffer and then write the data directly.  In this              way buffered streams will cascade harmlessly. */             flushBuffer();             out.write(cbuf, off, len);             return;         }         int b = off, t = off + len;         while(b < t) {             int d = min(nChars - nextChar, t - b);             System.arraycopy(cbuf, b, cb, nextChar, d);             b += d;             nextChar += d;             if(nextChar >= nChars)                 flushBuffer();         }     }     /**      * Writes a portion of a String.      *      * <p> If the value of the <tt>len</tt> parameter is negative then no      * characters are written.  This is contrary to the specification of this      * method in the {@linkplain java.io.Writer#write(java.lang.String,int,int)      * superclass}, which requires that an {@link IndexOutOfBoundsException} be      * thrown.      *      * @param  s     String to be written      * @param  off   Offset from which to start reading characters      * @param  len   Number of characters to be written      *      * @exception  IOException  If an I/O error occurs      */     public void write(String s, int off, int len) throws IOException {         int b = off, t = off + len;         while(b < t) {             int d = min(nChars - nextChar, t - b);             s.getChars(b, b + d, cb, nextChar);             b += d;             nextChar += d;             if(nextChar >= nChars)                 flushBuffer();         }     }     /**      * Flushes the stream.      *      * @exception  IOException  If an I/O error occurs      */     public void flush() throws IOException {         flushBuffer();         out.flush();     }     public void close() throws IOException {         if(out == null) {             return;         }         try {             flushBuffer();         } finally {             out.close();             out = null;             cb = null;         }     } }