196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/*
296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more
396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * contributor license agreements.  See the NOTICE file distributed with
496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * this work for additional information regarding copyright ownership.
596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0
696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * (the "License"); you may not use this file except in compliance with
796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * the License.  You may obtain a copy of the License at
896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *
996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
1096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *
1196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * See the License for the specific language governing permissions and
1596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * limitations under the License.
1696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */
1796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpackage org.apache.commons.io.output;
1896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
1996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.File;
2096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.FileInputStream;
2196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.FileOutputStream;
2296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.IOException;
2396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.OutputStream;
2496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
2596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport org.apache.commons.io.IOUtils;
2696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
2796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
2896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/**
2996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * An output stream which will retain data in memory until a specified
3096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * threshold is reached, and only then commit it to disk. If the stream is
3196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * closed before the threshold is reached, the data will not be written to
3296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * disk at all.
3396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p>
3496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * This class originated in FileUpload processing. In this use case, you do
3596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * not know in advance the size of the file being uploaded. If the file is small
3696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * you want to store it in memory (for speed), but if the file is large you want
3796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * to store it to file (to avoid memory issues).
3896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *
3996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @author <a href="mailto:martinc@apache.org">Martin Cooper</a>
4096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @author gaxzerow
4196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *
4296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @version $Id: DeferredFileOutputStream.java 606381 2007-12-22 02:03:16Z ggregory $
4396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */
4496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpublic class DeferredFileOutputStream
4596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    extends ThresholdingOutputStream
4696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project{
4796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
4896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    // ----------------------------------------------------------- Data members
4996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
5096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
5196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
5296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The output stream to which data will be written prior to the theshold
5396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * being reached.
5496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
5596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private ByteArrayOutputStream memoryOutputStream;
5696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
5796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
5896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
5996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The output stream to which data will be written at any given time. This
6096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * will always be one of <code>memoryOutputStream</code> or
6196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * <code>diskOutputStream</code>.
6296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
6396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private OutputStream currentOutputStream;
6496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
6596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
6696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
6796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The file to which output will be directed if the threshold is exceeded.
6896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
6996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private File outputFile;
7096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
7196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
7296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The temporary file prefix.
7396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
7496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private String prefix;
7596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
7696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
7796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The temporary file suffix.
7896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
7996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private String suffix;
8096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
8196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
8296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The directory to use for temporary files.
8396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
8496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private File directory;
8596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
8696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
8796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
8896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * True when close() has been called successfully.
8996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
9096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private boolean closed = false;
9196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
9296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    // ----------------------------------------------------------- Constructors
9396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
9496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
9596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
9696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Constructs an instance of this class which will trigger an event at the
9796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * specified threshold, and save data to a file beyond that point.
9896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
9996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param threshold  The number of bytes at which to trigger an event.
10096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param outputFile The file to which data is saved beyond the threshold.
10196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
10296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public DeferredFileOutputStream(int threshold, File outputFile)
10396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    {
10496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        super(threshold);
10596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        this.outputFile = outputFile;
10696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
10796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        memoryOutputStream = new ByteArrayOutputStream();
10896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        currentOutputStream = memoryOutputStream;
10996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
11096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
11196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
11296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
11396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Constructs an instance of this class which will trigger an event at the
11496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * specified threshold, and save data to a temporary file beyond that point.
11596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
11696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param threshold  The number of bytes at which to trigger an event.
11796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param prefix Prefix to use for the temporary file.
11896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param suffix Suffix to use for the temporary file.
11996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param directory Temporary file directory.
12096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
12196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @since Commons IO 1.4
12296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
12396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public DeferredFileOutputStream(int threshold, String prefix, String suffix, File directory)
12496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    {
12596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        this(threshold, (File)null);
12696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (prefix == null) {
12796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            throw new IllegalArgumentException("Temporary file prefix is missing");
12896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
12996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        this.prefix = prefix;
13096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        this.suffix = suffix;
13196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        this.directory = directory;
13296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
13396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
13496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
13596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    // --------------------------------------- ThresholdingOutputStream methods
13696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
13796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
13896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
13996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Returns the current output stream. This may be memory based or disk
14096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * based, depending on the current state with respect to the threshold.
14196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
14296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return The underlying output stream.
14396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
14496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @exception IOException if an error occurs.
14596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
14696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    protected OutputStream getStream() throws IOException
14796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    {
14896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return currentOutputStream;
14996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
15096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
15196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
15296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
15396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Switches the underlying output stream from a memory based stream to one
15496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * that is backed by disk. This is the point at which we realise that too
15596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * much data is being written to keep in memory, so we elect to switch to
15696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * disk-based storage.
15796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
15896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @exception IOException if an error occurs.
15996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
16096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    protected void thresholdReached() throws IOException
16196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    {
16296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (prefix != null) {
16396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            outputFile = File.createTempFile(prefix, suffix, directory);
16496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
16596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        FileOutputStream fos = new FileOutputStream(outputFile);
16696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        memoryOutputStream.writeTo(fos);
16796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        currentOutputStream = fos;
16896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        memoryOutputStream = null;
16996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
17096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
17196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
17296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    // --------------------------------------------------------- Public methods
17396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
17496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
17596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
17696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Determines whether or not the data for this output stream has been
17796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * retained in memory.
17896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
17996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return <code>true</code> if the data is available in memory;
18096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *         <code>false</code> otherwise.
18196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
18296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public boolean isInMemory()
18396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    {
18496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return (!isThresholdExceeded());
18596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
18696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
18796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
18896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
18996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Returns the data for this output stream as an array of bytes, assuming
19096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * that the data has been retained in memory. If the data was written to
19196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * disk, this method returns <code>null</code>.
19296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
19396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return The data for this output stream, or <code>null</code> if no such
19496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *         data is available.
19596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
19696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public byte[] getData()
19796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    {
19896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (memoryOutputStream != null)
19996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        {
20096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            return memoryOutputStream.toByteArray();
20196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
20296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return null;
20396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
20496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
20596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
20696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
20796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Returns either the output file specified in the constructor or
20896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * the temporary file created or null.
20996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * <p>
21096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * If the constructor specifying the file is used then it returns that
21196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * same output file, even when threashold has not been reached.
21296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * <p>
21396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * If constructor specifying a temporary file prefix/suffix is used
21496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * then the temporary file created once the threashold is reached is returned
21596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * If the threshold was not reached then <code>null</code> is returned.
21696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
21796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return The file for this output stream, or <code>null</code> if no such
21896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *         file exists.
21996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
22096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public File getFile()
22196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    {
22296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return outputFile;
22396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
22496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
22596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
22696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
22796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Closes underlying output stream, and mark this as closed
22896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
22996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @exception IOException if an error occurs.
23096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
23196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void close() throws IOException
23296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    {
23396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        super.close();
23496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        closed = true;
23596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
23696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
23796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
23896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
23996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Writes the data from this output stream to the specified output stream,
24096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * after it has been closed.
24196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
24296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param out output stream to write to.
24396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @exception IOException if this stream is not yet closed or an error occurs.
24496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
24596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void writeTo(OutputStream out) throws IOException
24696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    {
24796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // we may only need to check if this is closed if we are working with a file
24896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // but we should force the habit of closing wether we are working with
24996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // a file or memory.
25096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (!closed)
25196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        {
25296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            throw new IOException("Stream not closed");
25396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
25496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
25596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if(isInMemory())
25696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        {
25796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            memoryOutputStream.writeTo(out);
25896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
25996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        else
26096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        {
26196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            FileInputStream fis = new FileInputStream(outputFile);
26296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            try {
26396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                IOUtils.copy(fis, out);
26496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            } finally {
26596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                IOUtils.closeQuietly(fis);
26696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            }
26796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
26896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
26996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project}
270