This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git


The following commit(s) were added to refs/heads/master by this push:
     new ddbfad9  IO-651 Add DeferredFileOutputStream.getInputStream() (#206)
ddbfad9 is described below

commit ddbfad9b0b11136c2908e00e22732c0bc7369e83
Author: jmark109 <79322278+jmark...@users.noreply.github.com>
AuthorDate: Mon Feb 22 14:53:18 2021 -0500

    IO-651 Add DeferredFileOutputStream.getInputStream() (#206)
    
    Add DeferredFileOutputStream.getInputStream() for efficient retrieval of 
OutputSteam data.
    
    Co-authored-by: kare1634 <kare1...@incorporatedmail.com>
---
 .../io/output/DeferredFileOutputStream.java        | 31 +++++++++++++++
 .../io/output/DeferredFileOutputStreamTest.java    | 46 ++++++++++++++++++++++
 2 files changed, 77 insertions(+)

diff --git 
a/src/main/java/org/apache/commons/io/output/DeferredFileOutputStream.java 
b/src/main/java/org/apache/commons/io/output/DeferredFileOutputStream.java
index 25773fc..d6dac39 100644
--- a/src/main/java/org/apache/commons/io/output/DeferredFileOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/DeferredFileOutputStream.java
@@ -20,7 +20,9 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.Files;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
@@ -272,4 +274,33 @@ public class DeferredFileOutputStream extends 
ThresholdingOutputStream {
             }
         }
     }
+
+    /**
+     * Gets the current contents of this byte stream as an {@link InputStream}.
+     * If the data for this output stream has been retained in memory, the
+     * returned stream is backed by buffers of {@code this} stream,
+     * avoiding memory allocation and copy, thus saving space and time.<br>
+     * Otherwise, the returned stream will be one that is created from the data
+     * that has been committed to disk.
+     *
+     * @return the current contents of this output stream.
+     * @throws IOException if this stream is not yet closed or an error occurs.
+     * @see org.apache.commons.io.output.ByteArrayOutputStream#toInputStream()
+     * 
+     * @since 2.9
+     */
+    public InputStream toInputStream() throws IOException {
+        // we may only need to check if this is closed if we are working with 
a file
+        // but we should force the habit of closing whether we are working with
+        // a file or memory.
+        if (!closed) {
+            throw new IOException("Stream not closed");
+        }
+
+        if (isInMemory()) {
+            return memoryOutputStream.toInputStream();
+        } else {
+            return Files.newInputStream(outputFile.toPath());
+        }
+    }
 }
diff --git 
a/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java 
b/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java
index f5200c1..23a1c35 100644
--- 
a/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java
+++ 
b/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.commons.io.output;
 
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -27,9 +28,13 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.stream.IntStream;
 
+import org.apache.commons.io.IOUtils;
+import org.junit.jupiter.api.io.TempDir;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
@@ -365,4 +370,45 @@ public class DeferredFileOutputStreamTest {
             fail("Unexpected IOException");
         }
     }
+
+    /**
+     * Tests the case where the amount of data falls below the threshold, and 
is therefore confined to memory.
+     * Testing the getInputStream() method.
+     */
+    @ParameterizedTest(name = "initialBufferSize = {0}")
+    @MethodSource("data")
+    public void testBelowThresholdGetInputStream(final int initialBufferSize) 
throws IOException {
+        final DeferredFileOutputStream dfos = new 
DeferredFileOutputStream(testBytes.length + 42, initialBufferSize,
+            null);
+        dfos.write(testBytes, 0, testBytes.length);
+        dfos.close();
+        assertTrue(dfos.isInMemory());
+
+        try (InputStream is = dfos.toInputStream()) {
+            assertArrayEquals(testBytes, IOUtils.toByteArray(is));
+        }
+    }
+
+    /**
+     * Tests the case where the amount of data exceeds the threshold, and is 
therefore written to disk. The actual data
+     * written to disk is verified, as is the file itself.
+     * Testing the getInputStream() method.
+     */
+    @ParameterizedTest(name = "initialBufferSize = {0}")
+    @MethodSource("data")
+    public void testAboveThresholdGetInputStream(final int initialBufferSize, 
final @TempDir Path tempDir) throws IOException {
+        final File testFile = 
tempDir.resolve("testAboveThreshold.dat").toFile();
+
+        final DeferredFileOutputStream dfos = new 
DeferredFileOutputStream(testBytes.length - 5, initialBufferSize,
+            testFile);
+        dfos.write(testBytes, 0, testBytes.length);
+        dfos.close();
+        assertFalse(dfos.isInMemory());
+
+        try (InputStream is = dfos.toInputStream()) {
+            assertArrayEquals(testBytes, IOUtils.toByteArray(is));
+        }
+
+        verifyResultFile(testFile);
+    }
 }

Reply via email to