Class DeferrableOutputStream

java.lang.Object
java.io.OutputStream
org.apache.commons.fileupload2.core.DeferrableOutputStream
All Implemented Interfaces:
Closeable, Flushable, AutoCloseable

An OutputStream, which keeps its data in memory, until a configured threshold is reached. If that is the case, a temporary file is being created, and the in-memory data is transferred to that file. All following data will be written to that file, too. In other words: If an uploaded file is small, then it will be kept completely in memory. On the other hand, if the uploaded file's size exceeds the configured threshold, it it considered a large file, and the data is kept in a temporary file. More precisely, this output stream supports three modes of operation:
  1. threshold=-1: Always create a temporary file, even if the uploaded file is empty.
  2. threshold=0: Don't create empty, temporary files. (Create a temporary file, as soon as the first byte is written.)
  3. threshold>0: Create a temporary file, if the size exceeds the threshold, otherwise keep the file in memory.
Technically, this is similar to DeferredFileOutputStream, which has been used in the past, except that this implementation observes a precisely specified behavior, and semantics, that match the needs of the DiskFileItem. Background: Over the various versions of commons-io, the DeferredFileOutputStream has changed semantics, and behavior more than once. (For details, see FILEUPLOAD-295)
  • Constructor Details

    • DeferrableOutputStream

      public DeferrableOutputStream(int threshold, Supplier<Path> pathSupplier, DeferrableOutputStream.Listener listener) throws IOException
      Creates a new instance with the given threshold, and the given supplier for a temporary files path. If the threshold is -1, then the temporary file will be created immediately, and no in-memory data will be kept, at all. If the threshold is 0, then the temporary file will be created, as soon as the first byte will be written, but no in-memory data will be kept. If the threshold is > 0, then the temporary file will be created, as soon as that number of bytes have been written. Up to that point, data will be kept in an in-memory buffer.
      Parameters:
      threshold - Either of -1 (Create the temporary file immediately), 0 (Create the temporary file, as soon as data is being written for the first time), or >0 (Keep data in memory, as long as the given number of bytes is reached, then create a temporary file, and continue using that).
      pathSupplier - A supplier for the temporary files path. This supplier must not return null. The file's directory will be created, if necessary, by invoking Files.createDirectories(Path, java.nio.file.attribute.FileAttribute...).
      listener - An optional listener, which is being notified about important state changes.
      Throws:
      IOException - Creating the temporary file (in the case of threshold -1) has failed.
  • Method Details

    • checkThreshold

      protected OutputStream checkThreshold(int numberOfIncomingBytes) throws IOException
      Called to check, whether the threshold will be exceeded, if the given number of bytes are written to the stream. If so, persists the in-memory data by creating a new, temporary file, and writing the in-memory data to the file.
      Parameters:
      numberOfIncomingBytes - The number of bytes, which are about to be written.
      Returns:
      The actual output stream, to which the incoming data may be written. If the threshold is not yet exceeded, then this will be an internal ByteArrayOutputStream, otherwise a stream, which is writing to the temporary output file.
      Throws:
      IOException - Persisting the in-memory data to a temporary file has failed.
    • close

      public void close() throws IOException
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Overrides:
      close in class OutputStream
      Throws:
      IOException
    • getBytes

      public byte[] getBytes()
      Returns the data, that has been written, if the stream has been closed, and the stream is still in memory (isInMemory() returns true). Otherwise, returns null.
      Returns:
      If the stream is closed (no more data can be written), and the data is still in memory (no temporary file has been created), returns the data, that has been written. Otherwise, returns null.
    • getInputStream

      If the stream is closed: Returns an InputStream on the data, that has been written to this stream. Otherwise, throws an IllegalStateException.
      Returns:
      An InputStream on the data, that has been written. Never null.
      Throws:
      IllegalStateException - The stream has not yet been closed.
      IOException - Creating the InputStream has failed.
    • getPath

      public Path getPath()
      Returns the output file, that has been created, if any, or null. The latter is the case, if isInMemory() returns true.
      Returns:
      The output file, that has been created, if any, or null.
    • getSize

      public long getSize()
      Returns the number of bytes, that have been written to this stream.
      Returns:
      The number of bytes, that have been written to this stream.
    • getState

      Returns the streams current state.
      Returns:
      The streams current state.
    • getThreshold

      public int getThreshold()
      Returns the streams configured threshold.
      Returns:
      The streams configured threshold.
    • isInMemory

      public boolean isInMemory()
      Returns true, if this stream was never persisted, and no output file has been created.
      Returns:
      True, if the stream was never in state DeferrableOutputStream.State.persisted, otherwise false.
    • persist

      protected OutputStream persist() throws IOException
      Create the output file, change the state to persisted, and return an OutputStream, which is writing to that file.
      Returns:
      The OutputStream, which is writing to the created, temporary file.
      Throws:
      IOException - Creating the temporary file has failed.
    • write

      public void write(byte[] buffer) throws IOException
      Overrides:
      write in class OutputStream
      Throws:
      IOException
    • write

      public void write(byte[] buffer, int offset, int len) throws IOException
      Overrides:
      write in class OutputStream
      Throws:
      IOException
    • write

      public void write(int b) throws IOException
      Specified by:
      write in class OutputStream
      Throws:
      IOException