001: package it.unimi.dsi.fastutil.io;
002:
003: /*
004: * fastutil: Fast & compact type-specific collections for Java
005: *
006: * Copyright (C) 2005-2008 Sebastiano Vigna
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Lesser General Public
010: * License as published by the Free Software Foundation; either
011: * version 2.1 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public
019: * License along with this library; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021: *
022: */
023:
024: import java.io.IOException;
025: import java.io.OutputStream;
026:
027: /** Lightweight, unsynchronized output stream buffering class.
028: *
029: * <P>This class provides buffering for output streams, but all methods are unsynchronised.
030: *
031: * @since 4.4
032: */
033:
034: public class FastBufferedOutputStream extends OutputStream {
035: private static final boolean ASSERTS = false;
036:
037: /** The default size of the internal buffer in bytes (8Ki). */
038: public final static int DEFAULT_BUFFER_SIZE = 8 * 1024;
039:
040: /** The internal buffer. */
041: protected byte buffer[];
042:
043: /** The current position in the buffer. */
044: protected int pos;
045:
046: /** The number of buffer bytes available starting from {@link #pos}
047: * (it must be always equal to <code>buffer.length - pos</code>). */
048: protected int avail;
049:
050: /** The underlying output stream. */
051: protected OutputStream os;
052:
053: /** Creates a new fast buffered output stream by wrapping a given output stream with a given buffer size.
054: *
055: * @param os an output stream to wrap.
056: * @param bufferSize the size in bytes of the internal buffer.
057: */
058:
059: public FastBufferedOutputStream(final OutputStream os,
060: final int bufferSize) {
061: this .os = os;
062: buffer = new byte[bufferSize];
063: avail = bufferSize;
064: }
065:
066: /** Creates a new fast buffered ouptut stream by wrapping a given output stream with a buffer of {@link #DEFAULT_BUFFER_SIZE} bytes.
067: *
068: * @param os an output stream to wrap.
069: */
070: public FastBufferedOutputStream(final OutputStream os) {
071: this (os, DEFAULT_BUFFER_SIZE);
072: }
073:
074: private void dumpBuffer(final boolean ifFull) throws IOException {
075: if (!ifFull || avail == 0) {
076: os.write(buffer, 0, pos);
077: pos = 0;
078: avail = buffer.length;
079: }
080: }
081:
082: public void write(final int b) throws IOException {
083: if (ASSERTS)
084: assert avail > 0;
085: avail--;
086: buffer[pos++] = (byte) b;
087: dumpBuffer(true);
088: }
089:
090: public void write(final byte b[], final int offset, final int length)
091: throws IOException {
092: if (length >= buffer.length) {
093: dumpBuffer(false);
094: os.write(b, offset, length);
095: return;
096: }
097:
098: if (length <= avail) {
099: // Copy in buffer
100: System.arraycopy(b, offset, buffer, pos, length);
101: pos += length;
102: avail -= length;
103: dumpBuffer(true);
104: return;
105: }
106:
107: dumpBuffer(false);
108: System.arraycopy(b, offset, buffer, 0, length);
109: pos = length;
110: avail -= length;
111: }
112:
113: public void flush() throws IOException {
114: dumpBuffer(false);
115: os.flush();
116: }
117:
118: public void close() throws IOException {
119: if (os == null)
120: return;
121: flush();
122: if (os != System.out)
123: os.close();
124: os = null;
125: buffer = null;
126: }
127: }
|