1bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/* 2bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Licensed to the Apache Software Foundation (ASF) under one or more 3bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * contributor license agreements. See the NOTICE file distributed with 4bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * this work for additional information regarding copyright ownership. 5bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The ASF licenses this file to You under the Apache License, Version 2.0 6bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * (the "License"); you may not use this file except in compliance with 7bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the License. You may obtain a copy of the License at 8bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 9bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * http://www.apache.org/licenses/LICENSE-2.0 10bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 11bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Unless required by applicable law or agreed to in writing, software 12bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * distributed under the License is distributed on an "AS IS" BASIS, 13bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * See the License for the specific language governing permissions and 15bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * limitations under the License. 16bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 17bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpackage org.apache.commons.io.output; 18bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 19bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.File; 20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.FileInputStream; 21bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.FileOutputStream; 22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.IOException; 23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.OutputStream; 24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport org.apache.commons.io.IOUtils; 26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 27bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 28bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/** 29bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * An output stream which will retain data in memory until a specified 30bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * threshold is reached, and only then commit it to disk. If the stream is 31bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * closed before the threshold is reached, the data will not be written to 32bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * disk at all. 33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p> 34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This class originated in FileUpload processing. In this use case, you do 35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * not know in advance the size of the file being uploaded. If the file is small 36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * you want to store it in memory (for speed), but if the file is large you want 37bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * to store it to file (to avoid memory issues). 38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> 40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @author gaxzerow 41bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @version $Id: DeferredFileOutputStream.java 606381 2007-12-22 02:03:16Z ggregory $ 43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpublic class DeferredFileOutputStream 45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook extends ThresholdingOutputStream 46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook{ 47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // ----------------------------------------------------------- Data members 49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The output stream to which data will be written prior to the theshold 53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * being reached. 54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 55bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private ByteArrayOutputStream memoryOutputStream; 56bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 57bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 58bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 59bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The output stream to which data will be written at any given time. This 60bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * will always be one of <code>memoryOutputStream</code> or 61bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>diskOutputStream</code>. 62bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 63bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private OutputStream currentOutputStream; 64bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 65bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 66bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 67bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The file to which output will be directed if the threshold is exceeded. 68bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 69bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private File outputFile; 70bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 71bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 72bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The temporary file prefix. 73bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 74bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private String prefix; 75bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 76bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 77bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The temporary file suffix. 78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private String suffix; 80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The directory to use for temporary files. 83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private File directory; 85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 88bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * True when close() has been called successfully. 89bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 90bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private boolean closed = false; 91bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 92bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // ----------------------------------------------------------- Constructors 93bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 94bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 95bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 96bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Constructs an instance of this class which will trigger an event at the 97bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * specified threshold, and save data to a file beyond that point. 98bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 99bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param threshold The number of bytes at which to trigger an event. 100bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param outputFile The file to which data is saved beyond the threshold. 101bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 102bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public DeferredFileOutputStream(int threshold, File outputFile) 103bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 104bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook super(threshold); 105bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook this.outputFile = outputFile; 106bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 107bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook memoryOutputStream = new ByteArrayOutputStream(); 108bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook currentOutputStream = memoryOutputStream; 109bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 110bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Constructs an instance of this class which will trigger an event at the 114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * specified threshold, and save data to a temporary file beyond that point. 115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param threshold The number of bytes at which to trigger an event. 117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param prefix Prefix to use for the temporary file. 118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param suffix Suffix to use for the temporary file. 119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param directory Temporary file directory. 120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @since Commons IO 1.4 122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public DeferredFileOutputStream(int threshold, String prefix, String suffix, File directory) 124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook this(threshold, (File)null); 126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (prefix == null) { 127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new IllegalArgumentException("Temporary file prefix is missing"); 128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook this.prefix = prefix; 130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook this.suffix = suffix; 131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook this.directory = directory; 132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // --------------------------------------- ThresholdingOutputStream methods 136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Returns the current output stream. This may be memory based or disk 140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * based, depending on the current state with respect to the threshold. 141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return The underlying output stream. 143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @exception IOException if an error occurs. 145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected OutputStream getStream() throws IOException 147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return currentOutputStream; 149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 152bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 153bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Switches the underlying output stream from a memory based stream to one 154bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * that is backed by disk. This is the point at which we realise that too 155bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * much data is being written to keep in memory, so we elect to switch to 156bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * disk-based storage. 157bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 158bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @exception IOException if an error occurs. 159bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 160bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void thresholdReached() throws IOException 161bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 162bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (prefix != null) { 163bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook outputFile = File.createTempFile(prefix, suffix, directory); 164bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 165bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook FileOutputStream fos = new FileOutputStream(outputFile); 166bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook memoryOutputStream.writeTo(fos); 167bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook currentOutputStream = fos; 168bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook memoryOutputStream = null; 169bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 170bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 171bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 172bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // --------------------------------------------------------- Public methods 173bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 174bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 175bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 176bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Determines whether or not the data for this output stream has been 177bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * retained in memory. 178bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 179bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return <code>true</code> if the data is available in memory; 180bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>false</code> otherwise. 181bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 182bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public boolean isInMemory() 183bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 184bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return (!isThresholdExceeded()); 185bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 186bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 187bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 188bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 189bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Returns the data for this output stream as an array of bytes, assuming 190bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * that the data has been retained in memory. If the data was written to 191bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * disk, this method returns <code>null</code>. 192bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 193bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return The data for this output stream, or <code>null</code> if no such 194bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * data is available. 195bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 196bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public byte[] getData() 197bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 198bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (memoryOutputStream != null) 199bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 200bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return memoryOutputStream.toByteArray(); 201bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 202bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return null; 203bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 204bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 205bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 206bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 207bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Returns either the output file specified in the constructor or 208bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the temporary file created or null. 209bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p> 210bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * If the constructor specifying the file is used then it returns that 211bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * same output file, even when threashold has not been reached. 212bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p> 213bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * If constructor specifying a temporary file prefix/suffix is used 214bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * then the temporary file created once the threashold is reached is returned 215bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * If the threshold was not reached then <code>null</code> is returned. 216bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 217bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return The file for this output stream, or <code>null</code> if no such 218bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * file exists. 219bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 220bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public File getFile() 221bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 222bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return outputFile; 223bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 224bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 225bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 226bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 227bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Closes underlying output stream, and mark this as closed 228bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 229bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @exception IOException if an error occurs. 230bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 231bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void close() throws IOException 232bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 233bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook super.close(); 234bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook closed = true; 235bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 236bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 237bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 238bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 239bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Writes the data from this output stream to the specified output stream, 240bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * after it has been closed. 241bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 242bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param out output stream to write to. 243bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @exception IOException if this stream is not yet closed or an error occurs. 244bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 245bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void writeTo(OutputStream out) throws IOException 246bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 247bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // we may only need to check if this is closed if we are working with a file 248bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // but we should force the habit of closing wether we are working with 249bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // a file or memory. 250bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!closed) 251bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 252bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new IOException("Stream not closed"); 253bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 254bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 255bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if(isInMemory()) 256bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 257bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook memoryOutputStream.writeTo(out); 258bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 259bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook else 260bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook { 261bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook FileInputStream fis = new FileInputStream(outputFile); 262bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook try { 263bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook IOUtils.copy(fis, out); 264bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } finally { 265bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook IOUtils.closeQuietly(fis); 266bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 267bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 268bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 269bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook} 270