Skip to content

Commit cc65593

Browse files
author
Stephen Colebourne
committed
DeferredFileOutputStream.writeTo to allow current contents to be written to a stream
rfe 34173, from gaxzerow git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/io/trunk@280004 13f79535-47bb-0310-9956-ffa450edef68
1 parent b69e4cb commit cc65593

3 files changed

Lines changed: 133 additions & 6 deletions

File tree

RELEASE-NOTES.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,6 @@ Bug fixes from 1.0
5252
- CountingInputStream - skip(long)
5353
Bytes from calls to this method were not previously counted
5454

55-
- DeferredFileOutputStream
56-
???
57-
5855

5956
Enhancements from 1.0
6057
---------------------
@@ -127,6 +124,12 @@ Enhancements from 1.0
127124
- CountingInputStream,CountingOutputStream - resetCount()
128125
Adds the ability to reset the count part way through reading/writing the stream
129126

127+
- DeferredFileOutputStream - writeTo(OutputStream)
128+
New method to allow current contents to be written to a stream [34173]
129+
130+
- DeferredFileOutputStream
131+
Performance optimizations avoiding double buffering [34142]
132+
130133

131134
Feedback
132135
--------

src/java/org/apache/commons/io/output/DeferredFileOutputStream.java

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
package org.apache.commons.io.output;
1717

1818
import java.io.File;
19+
import java.io.FileInputStream;
1920
import java.io.FileOutputStream;
2021
import java.io.IOException;
2122
import java.io.OutputStream;
23+
import org.apache.commons.io.IOUtils;
24+
2225

2326
/**
2427
* <p>An output stream which will retain data in memory until a specified
@@ -32,6 +35,7 @@
3235
* to store it to file (to avoid memory issues).</p>
3336
*
3437
* @author <a href="mailto:martinc@apache.org">Martin Cooper</a>
38+
* @author gaxzerow
3539
*
3640
* @version $Id$
3741
*/
@@ -62,6 +66,11 @@ public class DeferredFileOutputStream
6266
*/
6367
private File outputFile;
6468

69+
70+
/**
71+
* True when close() has been called successfully.
72+
*/
73+
private boolean closed = false;
6574

6675
// ----------------------------------------------------------- Constructors
6776

@@ -152,9 +161,8 @@ public byte[] getData()
152161

153162

154163
/**
155-
* Returns the data for this output stream as a <code>File</code>, assuming
156-
* that the data was written to disk. If the data was retained in memory,
157-
* this method returns <code>null</code>.
164+
* Returns the same output file specified in the constructor, even when
165+
* threashold has not been reached.
158166
*
159167
* @return The file for this output stream, or <code>null</code> if no such
160168
* file exists.
@@ -163,4 +171,49 @@ public File getFile()
163171
{
164172
return outputFile;
165173
}
174+
175+
176+
/**
177+
* Closes underlying output stream, and mark this as closed
178+
*
179+
* @exception IOException if an error occurs.
180+
*/
181+
public void close() throws IOException
182+
{
183+
super.close();
184+
closed = true;
185+
}
186+
187+
188+
/**
189+
* Writes the data from this output stream to the specified output stream,
190+
* after it has been closed.
191+
*
192+
* @param out output stream to write to.
193+
* @exception IOException if this stream is not yet closed or an error occurs.
194+
*/
195+
public void writeTo(OutputStream out) throws IOException
196+
{
197+
// we may only need to check if this is closed if we are working with a file
198+
// but we should force the habit of closing wether we are working with
199+
// a file or memory.
200+
if (!closed)
201+
{
202+
throw new IOException("Stream not closed");
203+
}
204+
205+
if(isInMemory())
206+
{
207+
memoryOutputStream.writeTo(out);
208+
}
209+
else
210+
{
211+
FileInputStream fis = new FileInputStream(outputFile);
212+
try {
213+
IOUtils.copy(fis, out);
214+
} finally {
215+
IOUtils.closeQuietly(fis);
216+
}
217+
}
218+
}
166219
}

src/test/org/apache/commons/io/output/DeferredFileOutputStreamTest.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,77 @@ public void testThresholdReached() {
166166
// Ensure that the test starts from a clean base.
167167
testFile.delete();
168168
}
169+
170+
171+
/**
172+
* Test wether writeTo() properly writes small content.
173+
*/
174+
public void testWriteToSmall(){
175+
File testFile = new File("testWriteToMem.dat");
176+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
177+
// Ensure that the test starts from a clean base.
178+
testFile.delete();
179+
180+
DeferredFileOutputStream dfos =
181+
new DeferredFileOutputStream(testBytes.length *2, testFile);
182+
try{
183+
dfos.write(testBytes);
184+
185+
assertFalse(testFile.exists());
186+
assertTrue(dfos.isInMemory());
187+
188+
try {
189+
dfos.writeTo(baos);
190+
fail("Should not have been able to write before closing");
191+
} catch (IOException ioe) {
192+
// ok, as expected
193+
}
194+
195+
dfos.close();
196+
dfos.writeTo(baos);
197+
} catch (IOException ioe) {
198+
fail("Unexpected IOException");
199+
}
200+
byte[] copiedBytes = baos.toByteArray();
201+
assertTrue(Arrays.equals(testBytes, copiedBytes));
202+
203+
testFile.delete();
204+
}
205+
206+
/**
207+
* Test wether writeTo() properly writes large content.
208+
*/
209+
public void testWriteToLarge(){
210+
File testFile = new File("testWriteToFile.dat");
211+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
212+
// Ensure that the test starts from a clean base.
213+
testFile.delete();
214+
215+
DeferredFileOutputStream dfos =
216+
new DeferredFileOutputStream(testBytes.length /2, testFile);
217+
try{
218+
dfos.write(testBytes);
219+
220+
assertTrue(testFile.exists());
221+
assertFalse(dfos.isInMemory());
222+
223+
try {
224+
dfos.writeTo(baos);
225+
fail("Should not have been able to write before closeing");
226+
} catch (IOException ioe) {
227+
// ok, as expected
228+
}
229+
230+
dfos.close();
231+
dfos.writeTo(baos);
232+
} catch (IOException ioe) {
233+
fail("Unexpected IOException");
234+
}
235+
byte[] copiedBytes = baos.toByteArray();
236+
assertTrue(Arrays.equals(testBytes, copiedBytes));
237+
verifyResultFile(testFile);
238+
testFile.delete();
239+
}
169240

170241
/**
171242
* Verifies that the specified file contains the same data as the original

0 commit comments

Comments
 (0)