Class AsyncOutputStream
- All Implemented Interfaces:
Closeable
,Flushable
,AutoCloseable
OutputStream
that performs writes using a background thread, so that
write, flush, and close operations never block.
If the underlying output stream throws an IOException
during any operation,
this instance will re-throw the exception for all subsequent operations.
Instances use an internal buffer whose size is configured at construction time;
if the buffer overflows, a BufferOverflowException
is thrown. Alternately,
if a buffer size of zero is configured, the internal buffer will expand automatically as needed
(up to 231 bytes).
However, this creates a memory leak if the underlying OutputStream
blocks indefinitely.
Instances of this class are thread safe, and moreover writes are atomic: if multiple threads are writing at the same time the bytes written in any single method invocation are written contiguously to the underlying output.
-
Field Summary
Fields inherited from class java.io.FilterOutputStream
out
-
Constructor Summary
ConstructorDescriptionConvenience constructor for when an auto-expanding buffer is desired and a default thread name is to be used.AsyncOutputStream
(OutputStream out, int bufsize, String name) Constructor.AsyncOutputStream
(OutputStream out, String name) Convenience constructor for when an auto-expanding buffer is desired. -
Method Summary
Modifier and TypeMethodDescriptionint
Get the number of free bytes remaining in the output buffer.void
close()
Close this instance.void
flush()
Flush output.int
Get the capacity of this instance's output buffer.Get the exception thrown by the underlying output stream, if any.boolean
Determine if there is outstanding work still to be performed (writes, flushes, and/or close operations) by the background thread.boolean
waitForIdle
(long timeout) Wait for all outstanding work to complete.boolean
waitForSpace
(int numBytes, long timeout) Wait for buffer space availability.void
write
(byte[] data, int off, int len) Write data.void
write
(int b) Write data.Methods inherited from class java.io.FilterOutputStream
write
Methods inherited from class java.io.OutputStream
nullOutputStream
-
Field Details
-
log
-
-
Constructor Details
-
AsyncOutputStream
Convenience constructor for when an auto-expanding buffer is desired and a default thread name is to be used.- Parameters:
out
- underlying output stream- Throws:
IllegalArgumentException
- ifout
is null
-
AsyncOutputStream
Convenience constructor for when an auto-expanding buffer is desired.- Parameters:
out
- underlying output streamname
- name for this instance; used to create the name of the background thread- Throws:
IllegalArgumentException
- ifout
orname
is null
-
AsyncOutputStream
Constructor.- Parameters:
out
- underlying output streambufsize
- maximum number of bytes we can buffer, or zero for an auto-expanding buffer that has no fixed limitname
- name for this instance; used to create the name of the background thread- Throws:
IllegalArgumentException
- ifout
orname
is nullIllegalArgumentException
- ifbufsize
is negative
-
-
Method Details
-
write
Write data.This method will never block. To effect a normal blocking write, use
waitForSpace(int, long)
first.- Overrides:
write
in classFilterOutputStream
- Parameters:
b
- byte to write (lower 8 bits)- Throws:
IOException
- if an exception has been thrown by the underlying streamIOException
- if this instance has been closedBufferOverflowException
- if the buffer does not have room for the new byte
-
write
Write data.This method will never block. To effect a normal blocking write, invoke
waitForSpace(int, long)
first.- Overrides:
write
in classFilterOutputStream
- Parameters:
data
- bytes to writeoff
- starting offset in bufferlen
- number of bytes to write- Throws:
IOException
- if an exception has been thrown by the underlying streamIOException
- if this instance has been closedBufferOverflowException
- if the buffer does not have room for the new dataIllegalArgumentException
- iflen
is negative
-
flush
Flush output. This method will cause the underlying stream to be flushed once all of the data written to this instance at the time this method is invoked has been written to it.If additional data is written and then a second flush is requested before the first flush has actually occurred, the first flush will be canceled and only the second flush will be applied. Normally this is not a problem because the act of writing more data and then flushing forces earlier data to be flushed as well.
This method will never block. To block until the underlying flush operation completes, invoke
waitForIdle(long)
.- Specified by:
flush
in interfaceFlushable
- Overrides:
flush
in classFilterOutputStream
- Throws:
IOException
- if this instance has been closedIOException
- if an exception has been detected on the underlying streamIOException
- if the current thread is interrupted; the nested exception will anInterruptedException
-
close
Close this instance. This will (eventually) close the underlying output stream.If this instance has already been closed, nothing happens.
This method will never block. To block until the underlying close operation completes, invoke
waitForIdle(long)
.- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceCloseable
- Overrides:
close
in classFilterOutputStream
- Throws:
IOException
- if an exception has been detected on the underlying stream
-
getException
Get the exception thrown by the underlying output stream, if any.- Returns:
- thrown exception, or
null
if none has been thrown by the underlying stream
-
getBufferSize
public int getBufferSize()Get the capacity of this instance's output buffer.If a (fixed) non-zero value was given at construction time, this will return that value.
- Returns:
- current output buffer capacity
-
availableBufferSpace
Get the number of free bytes remaining in the output buffer.- Returns:
- current number of available bytes in the output buffer
- Throws:
IOException
- if this instance is or has been closedIOException
- if an exception has been detected on the underlying stream- See Also:
-
isWorkOutstanding
Determine if there is outstanding work still to be performed (writes, flushes, and/or close operations) by the background thread.- Returns:
- true if work remains to be done
- Throws:
IOException
- if this instance is or has been closedIOException
- if an exception has been detected on the underlying stream- See Also:
-
waitForSpace
Wait for buffer space availability.If a zero buffer size was configured at construction time, indicating an auto-expanding buffer, this will return immediately.
- Parameters:
numBytes
- amount of buffer space requiredtimeout
- maximum time to wait in milliseconds, or zero for infinite- Returns:
- true if space was found, false if time expired
- Throws:
IOException
- if this instance is or has been closedIOException
- if an exception has been detected on the underlying streamIllegalArgumentException
- ifnumBytes
is greater than the configured buffer sizeIllegalArgumentException
- iftimeout
is negativeInterruptedException
- if the current thread is interrupted- See Also:
-
waitForIdle
Wait for all outstanding work to complete.- Parameters:
timeout
- maximum time to wait in milliseconds, or zero for infinite- Returns:
- true for success, false if time expired
- Throws:
IOException
- if this instance is or has been closedIOException
- if an exception has been detected on the underlying streamIllegalArgumentException
- iftimeout
is negativeInterruptedException
- if the current thread is interrupted- See Also:
-