FileDocCategorySizeDatePackage
ByteArrayOutputStream.javaAPI DocAndroid 1.5 API10977Wed May 06 22:42:46 BST 2009org.apache.commons.io.output

ByteArrayOutputStream

public class ByteArrayOutputStream extends OutputStream
This class implements an output stream in which the data is written into a byte array. The buffer automatically grows as data is written to it.

The data can be retrieved using toByteArray() and toString().

Closing a ByteArrayOutputStream has no effect. The methods in this class can be called after the stream has been closed without generating an IOException.

This is an alternative implementation of the java.io.ByteArrayOutputStream class. The original implementation only allocates 32 bytes at the beginning. As this class is designed for heavy duty it starts at 1024 bytes. In contrast to the original it doesn't reallocate the whole memory block but allocates additional buffers. This way no buffers need to be garbage collected and the contents don't have to be copied to the new buffer. This class is designed to behave exactly like the original. The only exception is the deprecated toString(int) method that has been ignored.

author
Jeremias Maerki
author
Holger Hoffstatte
version
$Id: ByteArrayOutputStream.java 610010 2008-01-08 14:50:59Z niallp $

Fields Summary
private static final byte[]
EMPTY_BYTE_ARRAY
A singleton empty byte array.
private List
buffers
The list of buffers, which grows and never reduces.
private int
currentBufferIndex
The index of the current buffer.
private int
filledBufferSum
The total count of bytes in all the filled buffers.
private byte[]
currentBuffer
The current buffer.
private int
count
The total count of bytes written.
Constructors Summary
public ByteArrayOutputStream()
Creates a new byte array output stream. The buffer capacity is initially 1024 bytes, though its size increases if necessary.


                               
      
        this(1024);
    
public ByteArrayOutputStream(int size)
Creates a new byte array output stream, with a buffer capacity of the specified size, in bytes.

param
size the initial size
throws
IllegalArgumentException if size is negative

        if (size < 0) {
            throw new IllegalArgumentException(
                "Negative initial size: " + size);
        }
        needNewBuffer(size);
    
Methods Summary
public voidclose()
Closing a ByteArrayOutputStream has no effect. The methods in this class can be called after the stream has been closed without generating an IOException.

throws
IOException never (this method should not declare this exception but it has to now due to backwards compatability)

        //nop
    
private byte[]getBuffer(int index)
Return the appropriate byte[] buffer specified by index.

param
index the index of the buffer required
return
the buffer

        return (byte[]) buffers.get(index);
    
private voidneedNewBuffer(int newcount)
Makes a new buffer available either by allocating a new one or re-cycling an existing one.

param
newcount the size of the buffer if one is created

        if (currentBufferIndex < buffers.size() - 1) {
            //Recycling old buffer
            filledBufferSum += currentBuffer.length;
            
            currentBufferIndex++;
            currentBuffer = getBuffer(currentBufferIndex);
        } else {
            //Creating new buffer
            int newBufferSize;
            if (currentBuffer == null) {
                newBufferSize = newcount;
                filledBufferSum = 0;
            } else {
                newBufferSize = Math.max(
                    currentBuffer.length << 1, 
                    newcount - filledBufferSum);
                filledBufferSum += currentBuffer.length;
            }
            
            currentBufferIndex++;
            currentBuffer = new byte[newBufferSize];
            buffers.add(currentBuffer);
        }
    
public synchronized voidreset()

see
java.io.ByteArrayOutputStream#reset()

        count = 0;
        filledBufferSum = 0;
        currentBufferIndex = 0;
        currentBuffer = getBuffer(currentBufferIndex);
    
public synchronized intsize()
Return the current size of the byte array.

return
the current size of the byte array

        return count;
    
public synchronized byte[]toByteArray()
Gets the curent contents of this byte stream as a byte array. The result is independent of this stream.

return
the current contents of this output stream, as a byte array
see
java.io.ByteArrayOutputStream#toByteArray()

        int remaining = count;
        if (remaining == 0) {
            return EMPTY_BYTE_ARRAY; 
        }
        byte newbuf[] = new byte[remaining];
        int pos = 0;
        for (int i = 0; i < buffers.size(); i++) {
            byte[] buf = getBuffer(i);
            int c = Math.min(buf.length, remaining);
            System.arraycopy(buf, 0, newbuf, pos, c);
            pos += c;
            remaining -= c;
            if (remaining == 0) {
                break;
            }
        }
        return newbuf;
    
public java.lang.StringtoString()
Gets the curent contents of this byte stream as a string.

return
the contents of the byte array as a String
see
java.io.ByteArrayOutputStream#toString()

        return new String(toByteArray());
    
public java.lang.StringtoString(java.lang.String enc)
Gets the curent contents of this byte stream as a string using the specified encoding.

param
enc the name of the character encoding
return
the string converted from the byte array
throws
UnsupportedEncodingException if the encoding is not supported
see
java.io.ByteArrayOutputStream#toString(String)

        return new String(toByteArray(), enc);
    
public voidwrite(byte[] b, int off, int len)
Write the bytes to byte array.

param
b the bytes to write
param
off The start offset
param
len The number of bytes to write

        if ((off < 0) 
                || (off > b.length) 
                || (len < 0) 
                || ((off + len) > b.length) 
                || ((off + len) < 0)) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return;
        }
        synchronized (this) {
            int newcount = count + len;
            int remaining = len;
            int inBufferPos = count - filledBufferSum;
            while (remaining > 0) {
                int part = Math.min(remaining, currentBuffer.length - inBufferPos);
                System.arraycopy(b, off + len - remaining, currentBuffer, inBufferPos, part);
                remaining -= part;
                if (remaining > 0) {
                    needNewBuffer(newcount);
                    inBufferPos = 0;
                }
            }
            count = newcount;
        }
    
public synchronized voidwrite(int b)
Write a byte to byte array.

param
b the byte to write

        int inBufferPos = count - filledBufferSum;
        if (inBufferPos == currentBuffer.length) {
            needNewBuffer(count + 1);
            inBufferPos = 0;
        }
        currentBuffer[inBufferPos] = (byte) b;
        count++;
    
public synchronized intwrite(java.io.InputStream in)
Writes the entire contents of the specified input stream to this byte stream. Bytes from the input stream are read directly into the internal buffers of this streams.

param
in the input stream to read from
return
total number of bytes read from the input stream (and written to this stream)
throws
IOException if an I/O error occurs while reading the input stream
since
Commons IO 1.4

        int readCount = 0;
        int inBufferPos = count - filledBufferSum;
        int n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
        while (n != -1) {
            readCount += n;
            inBufferPos += n;
            count += n;
            if (inBufferPos == currentBuffer.length) {
                needNewBuffer(currentBuffer.length);
                inBufferPos = 0;
            }
            n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
        }
        return readCount;
    
public synchronized voidwriteTo(java.io.OutputStream out)
Writes the entire contents of this byte stream to the specified output stream.

param
out the output stream to write to
throws
IOException if an I/O error occurs, such as if the stream is closed
see
java.io.ByteArrayOutputStream#writeTo(OutputStream)

        int remaining = count;
        for (int i = 0; i < buffers.size(); i++) {
            byte[] buf = getBuffer(i);
            int c = Math.min(buf.length, remaining);
            out.write(buf, 0, c);
            remaining -= c;
            if (remaining == 0) {
                break;
            }
        }