Java OutputStream
Jakob Jenkov |
The Java OutputStream class, java.io.OutputStream
, is the base class of all
output streams in the Java IO API. Subclasses of OutputStream
include
the Java BufferedOutputStream and the
Java FileOutputStream among others. To see a full
list of output streams, go to the bottom table of the Java IO Overview page.
Java OutputStream Subclasses
Here are some of the well-known subclasses of the Java OutputStream class:
- ByteArrayOutputStream
- FileOutputStream
- PipedOutputStream
- BufferedOutputStream
- FilterOutputStream
- DataOutputStream
- PrintStream
- ObjectOutputStream
OutputStream's and Destinations
A Java OutputStream
is typically connected to some data destination - as mentioned in
the Java IO Overview, like a file, network connection,
pipe, memory buffer etc. This is also explained in more detail in the Java IO Overview text.
The OutputStream
's data destination is where all data written to the OutputStream
will
eventually end.
write(byte)
The write(byte)
method is used to write a single byte
to the Java OutputStream
.
The write()
method of an OutputStream
takes an int which contains the byte value of the
byte to write. Only the first byte of the int
value is written. The rest is ignored.
Subclasses of OutputStream
may have alternative write()
methods. For instance, the
DataOutputStream
allows you to write Java primitives like int, long, float, double, boolean etc.
with its corresponding methods writeBoolean()
, writeDouble()
etc.
Here is an OutputStream
write()
example:
OutputStream outputStream = new FileOutputStream("c:\\data\\output-text.txt"); while(hasMoreData()) { int data = getMoreData(); outputStream.write(data); } outputStream.close();
This OutputStream
write()
example first creates a FileOutputStream
to which
the data will be written. Then the example enters a while
loop. The condition to exit the while loop
is the return value of the method hasMoreData()
. The implementation of hasMoreData()
is
not shown, but imagine that it returns true if there is more data to write, and false if not.
Inside the while loop the example calls the method getMoreData()
to get the next data to write to
the OutputStream
, and then writes that data to the OutputStream
. The while loop
continues until hasMoreData()
returns false.
Note: The proper exception handling has been skipped here for the sake of clarity. To learn more about correct exception handling, go to Java IO Exception Handling.
write(byte[])
The Java OutputStream
has to write-methods that enable you to write an array of bytes to
the OutputStream
at a time. These write-methods are:
write(byte[] bytes)
write(byte[] bytes, int offset, int length)
The write(byte[] bytes)
method writes all the bytes in the byte
array to the
OutputStream
.
The write(byte[] bytes, int offset, int length)
method writes length
bytes
starting from index offset
from the byte array to the OutputStream
.
Both of these methods return the actual number of bytes written to the OutputStream
, if not
the whole array, or length
bytes could be written as requested.
Here is an example of writing an array of bytes to a Java OutputStream
using the second of
these two write methods:
OutputStream outputStream = new FileOutputStream("/usr/home/jakobjenkov/output.txt"); byte[] sourceBytes = ... // get source bytes from somewhere. int bytesWritten = outputStream.write(sourceBytes, 0, sourceBytes.length);
This example will instruct the OutputStream
to attempt to write all bytes in the
sourceBytes
array to the OutputStream
. After executing this code the
bytesWritten
variable will contain the number of bytes actually written to the
OutputStream
.
Write Performance
It is faster to write an array of bytes to a Java OutputStream than writing one byte at a time. The speedup
can be quite significant - up to 10 x higher or more. Therefore it is recommended to use the write(byte[])
methods whenever possible.
The exact speedup you get depends on the underlying OS and hardware of the computer you run the Java code on.
The speedup depends on issues like memory speed, hard disk speed and buffer sizes, or network card speed and buffer
sizes, depending on which destination the OutputStream
sends its data to.
Transparent Buffering via BufferedOutputStream
You can get transparent buffering of bytes written to a Java OutputStream
by wrapping it in a
Java BufferedOutputStream . All bytes written to the BufferedOutputStream
will first get buffered inside an internal byte array in the BufferedOutputStream
. When the buffer is
full, the buffer is flushed to the underlying OutputStream
all at once.
Here is an example of wrapping a Java OutputStream
in a BufferedOutputStream
:
int bufferSize = 8 * 1024; OutputStream outputStream = new BufferedOutputStream( new FileOutputStream("c:\\data\\output-file.txt"), bufferSize);
You can read more about the BufferedOutputStream
in my BufferedOutputStream tutorial.
flush()
The Java OutputStream
's flush()
method flushes all data written to the OutputStream
to the underlying data destination. For instance, if the OutputStream
is a FileOutputStream
then bytes written to the FileOutputStream
may not have been fully written to disk yet. The data might
be buffered in OS memory somewhere, even if your Java code has written it to the FileOutputStream
.
By calling flush()
you can assure that any buffered data will be flushed (written) to disk (or network, or whatever
else the destination of your OutputStream
has). Here is an example of flushing data written to
a Java OutputStream
by calling its flush()
method:
outputStream.flush();
Close an OutputStream
Once you are done writing data to a Java OutputStream
you should close it. You close an
OutputStream
by calling its close()
method.
Here is an example of closing a Java OutputStream
:
OutputStream outputStream = new FileOutputStream("c:\\data\\output-text.txt"); while(hasMoreData()) { int data = getMoreData(); outputStream.write(data); } outputStream.close();
The concrete implementations of hasMoreData()
and getMoreData()
are left out, but
they are not really super important to understand the principle of this example. What matters is, that
once the while
loop ends, and you are done writing data to the OutputStream
,
its close()
method is called, which closes the OutputStream
.
The above example is not fully robust though. In case the write()
method throws an exception,
the close()
method will never get called. The exception will make the program exit whatever
method the above code is located in.
Instead, you should use the
Java try with resources construct to close
the OutputStream
. Here is an example that closes a Java OutputStream
using
the try-with-resources construct:
try( OutputStream outputStream = new FileOutputStream("c:\\data\\output-text.txt")) { while(hasMoreData()) { int data = getMoreData(); outputStream.write(data); } }
Once the try
block is exited, the close()
method of the OutputStream
is called automatically, because the OutputStream
was declared inside the parentheses of the
try
block. Even if an exception is thrown from inside the try
block, the
close()
method is still called before the exception is propagated up the call stack.
Convert OutputStream to Writer
The Java OutputStream
is a byte based stream. You can convert a OutputStream
to a
character based Writer
using the Java OutputStreamWriter class.
Here is an example of converting a Java OutputStream
to a Writer
using
OutputStreamWriter
:
OutputStream outputStream = new FileOutputStream("c:\\data\\output.txt"); Writer outputStreamWriter = new OutputStreamWriter(outputStream); outputStreamWriter.write("Hello World");
You can read more about how to use the OutputStreamWriter
including how to set the character encoding
to use when converting characters to bytes in my OutputStreamWriter tutorial.
Tweet | |
Jakob Jenkov |