Immediately following Indexwriter: Lucene Index Creation and Maintenance, IndexOutput, a random-access output stream. is used for all Lucene index output operations.

IndexOutput is binded with Directory, which can be easily deduced from Class Diagram,

and also from source code:

// Directory.java

public abstract class Directory implements Closeable {
  /** Creates a new, empty file in the directory with the given name.
      Returns a stream writing this file. */
  public abstract IndexOutput createOutput(String name, IOContext context) throws IOException;
}

Remember SimpleTextStoredFieldsWriter? It is initialized with one Directory instance.

// SimpleTextStoredFieldsFormat.java

public class SimpleTextStoredFieldsFormat extends StoredFieldsFormat {

  @Override
  public StoredFieldsWriter fieldsWriter(Directory directory, SegmentInfo si, IOContext context) throws IOException {
    return new SimpleTextStoredFieldsWriter(directory, si.name, context);
  }
}

Put Directory aside, let’s focus on IndexOutput.

DataOutput

DataOutput is abstract base class for performing write operations of Lucene’s low-level data types. The instrument of method can be inferred from its name:

  • writeInt
  • writeInt
  • writeString
// DataOutput.java

public abstract class DataOutput {
  public abstract void writeByte(byte b) throws IOException;

  // Writes a single byte
  public abstract void writeByte(byte b) throws IOException;

  // Writes an int as for bytes
  public void writeInt(int i) throws IOException {
    writeByte((byte)(i >> 24));
    writeByte((byte)(i >> 16));
    writeByte((byte)(i >>  8));
    writeByte((byte) i);
  }

  // Writes a string
  public void writeString(String s) throws IOException {
    final BytesRef utf8Result = new BytesRef(s);
    writeVInt(utf8Result.length);
    writeBytes(utf8Result.bytes, utf8Result.offset, utf8Result.length);
  }
}

IndexOutput

IndexOutput extends DataOutput and imlements Closeable which requires it override close method. Besides this, IndexOutput affiliates name and description for DataOutput.

// IndexOutput.java

public abstract class IndexOutput extends DataOutput implements Closeable {
  /** Full description of this output, e.g. which class such as FSIndexOutput, and the full path to the file */
  private final String resourceDescription;

  /** Just the name part from resourceDescription */
  private final String name;

  @Override
  public abstract void close() throws IOException;
}

OutputStreamIndexOutput

When it comes to OutputStreamIndexOutput, the derived of IndexOutput, it implements for buffered that wites to an OutputStream.

// OutputStreamIndexOutput.java

public class OutputStreamIndexOutput extends IndexOutput {
  private final BufferedOutputStream os;

  @Override
  public final void writeByte(byte b) throws IOException {
    os.write(b);
    bytesWritten++;
  }

  @Override
  public void close() throws IOException {
    try (final OutputStream o = os) {
      // We want to make sure that os.flush() was running before close:
      // BufferedOutputStream may ignore IOExceptions while flushing on close().
      // We keep this also in Java 8, although it claims to be fixed there,
      // because there are more bugs around this! See:
      // # https://bugs.openjdk.java.net/browse/JDK-7015589
      // # https://bugs.openjdk.java.net/browse/JDK-8054565
      if (!flushedOnClose) {
        flushedOnClose = true; // set this BEFORE calling flush!
        o.flush();
      }
    }
  }
}

For more details about BufferedOutputStream, go to java.io.BufferedOutputStream.