ByteArrayOutputStream writes bytes to a byte array in memory. Not to any other destination, such as a file or a network socket. After writing the data, you can get the byte array by calling toByteArray() on it.
BufferedOutputStream wraps another, underlying OutputStream and provides buffering for that underlying stream, to make I/O operations more efficient. The underlying stream can be any kind of OutputStream, for example one that writes to a file or a network socket.
Why you might want to use buffering: Writing a large block of data to the file system is more efficient than writing byte by byte. If your program needs to write many small pieces of data, it's more efficient to first gather these small pieces in a buffer and then write the entire buffer to disk at once. This is what BufferedOutputStream does automatically for you.
java - Difference between ByteArrayOutputStream and BufferedOutputStream - Stack Overflow
FileOutputStream v. ByteArrayOutputStream: is there a noticeable difference in memory usage?
java - How to fill a ByteArrayOutputStream with the content of a file? - Stack Overflow
ByteArrayOutputStream to a File - Drive API, Java
Videos
ByteArrayOutputStream writes bytes to a byte array in memory. Not to any other destination, such as a file or a network socket. After writing the data, you can get the byte array by calling toByteArray() on it.
BufferedOutputStream wraps another, underlying OutputStream and provides buffering for that underlying stream, to make I/O operations more efficient. The underlying stream can be any kind of OutputStream, for example one that writes to a file or a network socket.
Why you might want to use buffering: Writing a large block of data to the file system is more efficient than writing byte by byte. If your program needs to write many small pieces of data, it's more efficient to first gather these small pieces in a buffer and then write the entire buffer to disk at once. This is what BufferedOutputStream does automatically for you.
Just look at the javadoc:
ByteArrayOutputStream:
This class implements an output stream in which the data is written into a byte array.
BufferedOutputStream:
The class implements a buffered output stream. By setting up such an output stream, an application can write bytes to the underlying output stream without necessarily causing a call to the underlying system for each byte written.
So, those are really two very different things:
- the first one you use when you know that you have some data that in the end you need as array of bytes
- the second one is just a wrapper around any other kind of output stream - which adds buffering.
That is all there is to this!
And if you want to experience a different behavior: create a buffered one that writes to a file, and an array one. Then just keep pushing bytes into each one. The array one will cause a memory problem at some point, the other one might not stop until all of your disk space is used up.
Scenario: I have a REST API endpoint built with Spring Boot. The endpoint is used to dynamically generate an excel file based off input parameters. When the file is done being generated, it returns the file as an InputStreamResource. The main goal is minimum memory usage.
I'm using fastexcel to create the excel file, and I'm flushing it to the OutputStream after every row is written. Right now, I am using a FileOutputStream to write to disk. When the excel file is done being generated, I read it back in using InputStreamResource and stream the response. My thought process is that a ByteArrayOutputStream keeps everything in memory even if I'm flushing the excel file after every row, so I used the FileOutputStream. Does my logic track here? Or am I unnecessarily slowing things down with expensive filesystem IO?
java.nio.file.Files.readAllBytes() can be of help in Java 7.
Read all the bytes from a file. The method ensures that the file is closed when all bytes have been read or an I/O error, or other runtime exception, is thrown.
Note that this method is intended for simple cases where it is convenient to read all bytes into a byte array. It is not intended for reading in large files.
The more conventional way would be to use a
FileInputStreamandread()the file to abyte[].Apache Commons IO has byte[] org.apache.commons.io.IOUtils.toByteArray(InputStream input) method.
Google's Guava got ByteStreams.toByteArray(InputStream) and Files.toByteArray(File).
Here's the old fashioned way to read from a file into a ByteArrayOutputStream.
public void getBytes(String fileName) throws FileNotFoundException,
IOException {
byte[] buffer = new byte[4096];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
fileName));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bytes = 0;
while ((bytes = bis.read(buffer, 0, buffer.length)) > 0) {
baos.write(buffer, 0, bytes);
}
baos.close();
bis.close();
}