Java Streams   «Prev  Next»

Lesson 1

Writing Data Using Java Streams

This module introduces how to use streams to write data. In addition, you will learn how to use various methods to make using output streams more efficient. In this module, you will learn the following:
  1. How to copy a file to System.out with maximum efficiency
  2. When to flush and close an output stream
  3. How to use file streams

As in the previous module, all data in this module will be raw bytes. Later modules will show you how to read and write data without explicitly converting it to and from bytes first.

Classic Java Streams (Java 1.1) used to write data from byte code to file

In classic Java Streams (Java 1.1), you can use the FileOutputStream and DataOutputStream classes to write data from byte code to a file. Here's an example of how to use these classes:
import java.io.*;

public class WriteToFileExample {
  public static void main(String[] args) {
    try {
      // create a new file output stream
      FileOutputStream fos = new FileOutputStream("output.txt");
      
      // create a new data output stream
      DataOutputStream dos = new DataOutputStream(fos);
      
      // write some data to the stream
      dos.writeBytes("Hello, world!");
      
      // close the streams
      dos.close();
      fos.close();
      
      System.out.println("Data has been written to the file.");
    } catch (IOException e) {
      System.err.println("Error writing to file: " + e.getMessage());
    }
  }
}


In this example, a FileOutputStream is created for the "output.txt" file, which creates a new file if it does not already exist. A DataOutputStream is then created, which allows for writing data to the file in various primitive data types such as int, boolean, and double. In this case, the writeBytes() method is used to write the string "Hello, world!" to the file as a sequence of bytes. Once the data has been written to the file, the DataOutputStream and FileOutputStream are closed using the close() method. If an error occurs while writing to the file, an IOException is caught and an error message is printed. Note that in classic Java Streams, it's important to ensure that the streams are properly closed after use to avoid resource leaks and data corruption.


The java.io.OutputStream class declares the three basic methods you need to write bytes of data onto a stream. It also has methods for closing and flushing streams
public abstract void write(int b) throws IOException
public void write(byte[] data) throws IOException
public void write(byte[] data, int offset, int length) throws IOException

public void flush() throws IOException
public void close() throws IOException

OutputStream is an abstract class and subclasses provide implementations of the abstract write(int b) method. They may also override the four nonabstract methods. For example, the FileOutputStream class overrides all five methods with native methods that know how to write bytes into files on the host platform. Although OutputStream is abstract, often you only need to know that the object you have is an OutputStream ; the more specific subclass of OutputStream is hidden from you.

For example, the getOutputStream() method of java.net.URLConnection has the signature:
public OutputStream getOutputStream() throws IOException


Depending on the type of URL associated with this URLConnection object, the actual class of the output stream that's returned may be a
  1. sun.net.TelnetOutputStream ,
  2. a sun.net.smtp.SmtpPrintStream ,
  3. a sun.net.www.http.KeepAliveStream.
All you know as a programmer, and all you need to know, is that the object returned is in fact some instance of OutputStream. That is why the detailed classes that handle particular kinds of connections are hidden inside the packages. Furthermore, even when working with subclasses whose types you know, you still need to be able to use the methods inherited from OutputStream. Since methods that are inherited are not included in the online documentation, it is important to remember that they are there. For example, the java.io.DataOutputStream class does not declare a close() method, but you can still call the one it inherits from its superclass.