Author: sebb
Date: Sat Mar 17 01:21:11 2012
New Revision: 1301851

URL: http://svn.apache.org/viewvc?rev=1301851&view=rev
Log:
IO-305:  New copyLarge() method in IOUtils that takes additional offset, length 
arguments

Modified:
    commons/proper/io/trunk/RELEASE-NOTES.txt
    commons/proper/io/trunk/src/changes/changes.xml
    commons/proper/io/trunk/src/main/java/org/apache/commons/io/IOUtils.java
    
commons/proper/io/trunk/src/test/java/org/apache/commons/io/IOUtilsTestCase.java

Modified: commons/proper/io/trunk/RELEASE-NOTES.txt
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/RELEASE-NOTES.txt?rev=1301851&r1=1301850&r2=1301851&view=diff
==============================================================================
--- commons/proper/io/trunk/RELEASE-NOTES.txt (original)
+++ commons/proper/io/trunk/RELEASE-NOTES.txt Sat Mar 17 01:21:11 2012
@@ -24,6 +24,7 @@ $release.description.replaceAll("  ", "
 Changes in this version include:
 
 New features:
+o IO-305:  New copyLarge() method in IOUtils that takes additional offset, 
length arguments Thanks to Manoj Mokashi. 
 o IO-287:  Use terabyte (TB) , petabyte (PB) and exabyte (EB) in 
FileUtils.byteCountToDisplaySize(long size) Thanks to Ron Kuris, Gary Gregory. 
 o IO-173:  FileUtils.listFiles() doesn't return directories Thanks to Marcos 
Vinícius da Silva. 
 o IO-297:  CharSequenceInputStream to efficiently stream content of a 
CharSequence Thanks to Oleg Kalnichevski. 

Modified: commons/proper/io/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/changes/changes.xml?rev=1301851&r1=1301850&r2=1301851&view=diff
==============================================================================
--- commons/proper/io/trunk/src/changes/changes.xml (original)
+++ commons/proper/io/trunk/src/changes/changes.xml Sat Mar 17 01:21:11 2012
@@ -40,6 +40,9 @@ The <action> type attribute can be add,u
 
   <body>
     <release version="2.2" date="TBA">
+      <action issue="IO-305" dev="sebb" type="add" due-to="Manoj Mokashi">
+        New copyLarge() method in IOUtils that takes additional offset, length 
arguments
+      </action>        
       <action issue="IO-300" dev="sebb" type="fix">
         FileUtils.moveDirectoryToDirectory removes source directory if 
destination is a subdirectory
       </action>        

Modified: 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/IOUtils.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/IOUtils.java?rev=1301851&r1=1301850&r2=1301851&view=diff
==============================================================================
--- commons/proper/io/trunk/src/main/java/org/apache/commons/io/IOUtils.java 
(original)
+++ commons/proper/io/trunk/src/main/java/org/apache/commons/io/IOUtils.java 
Sat Mar 17 01:21:11 2012
@@ -1458,6 +1458,51 @@ public class IOUtils {
     }
 
     /**
+     * Copy some or all bytes from a large (over 2GB) <code>InputStream</code> 
to an
+     * <code>OutputStream</code>, optionally skipping input bytes.
+     * <p>
+     * This method buffers the input internally, so there is no need to use a
+     * <code>BufferedInputStream</code>.
+     * <p>
+     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
+     * 
+     * @param input  the <code>InputStream</code> to read from
+     * @param output  the <code>OutputStream</code> to write to
+     * @param offset : number of bytes to skip from input before copying
+     *         -ve values are ignored
+     * @param length : number of bytes to copy. -ve means all
+     * @return the number of bytes copied
+     * @throws NullPointerException if the input or output is null
+     * @throws IOException if an I/O error occurs
+     * @since Commons IO 2.2
+     */
+    public static long copyLarge(InputStream input, OutputStream output, final 
long offset, final long length)
+            throws IOException {
+        if( offset > 0){
+            skipFully( input, offset);
+        }
+        if (length == 0) {
+            return 0;
+        }
+        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+        int bytesToRead = buffer.length;
+        if (length > 0 && length < buffer.length) {
+            bytesToRead = (int) length;
+        }
+        int read;
+        long totalRead = 0;
+        while(bytesToRead > 0 && -1 != (read=input.read(buffer, 0, 
bytesToRead))) {
+            output.write( buffer, 0, read);
+            totalRead += read;
+            if (length > 0) { // only adjust length if not reading to the end
+                // Note the cast must work because buffer.length is an integer
+                bytesToRead = (int) Math.min(length - totalRead, 
buffer.length);
+            }
+        }
+        return totalRead;
+    }
+
+    /**
      * Copy bytes from an <code>InputStream</code> to chars on a
      * <code>Writer</code> using the default character encoding of the 
platform.
      * <p>
@@ -1562,6 +1607,51 @@ public class IOUtils {
     }
 
     /**
+     * Copy some or all chars from a large (over 2GB) <code>InputStream</code> 
to an
+     * <code>OutputStream</code>, optionally skipping input chars.
+     * <p>
+     * This method buffers the input internally, so there is no need to use a
+     * <code>BufferedReader</code>.
+     * <p>
+     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
+     * 
+     * @param input  the <code>Reader</code> to read from
+     * @param output  the <code>Writer</code> to write to
+     * @param offset : number of chars to skip from input before copying
+     *         -ve values are ignored
+     * @param length : number of chars to copy. -ve means all
+     * @return the number of chars copied
+     * @throws NullPointerException if the input or output is null
+     * @throws IOException if an I/O error occurs
+     * @since Commons IO 2.2
+     */
+    public static long copyLarge(Reader input, Writer output, final long 
offset, final long length)
+            throws IOException {
+        if( offset > 0){
+            skipFully( input, offset);
+        }
+        if (length == 0) {
+            return 0;
+        }
+        char[] buffer = new char[DEFAULT_BUFFER_SIZE];
+        int bytesToRead = buffer.length;
+        if (length > 0 && length < buffer.length) {
+            bytesToRead = (int) length;
+        }
+        int read;
+        long totalRead = 0;
+        while(bytesToRead > 0 && -1 != (read=input.read(buffer, 0, 
bytesToRead))) {
+            output.write( buffer, 0, read);
+            totalRead += read;
+            if (length > 0) { // only adjust length if not reading to the end
+                // Note the cast must work because buffer.length is an integer
+                bytesToRead = (int) Math.min(length - totalRead, 
buffer.length);
+            }
+        }
+        return totalRead;
+    }
+
+    /**
      * Copy chars from a <code>Reader</code> to bytes on an
      * <code>OutputStream</code> using the default character encoding of the
      * platform, and calling flush.

Modified: 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/IOUtilsTestCase.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/IOUtilsTestCase.java?rev=1301851&r1=1301850&r2=1301851&view=diff
==============================================================================
--- 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/IOUtilsTestCase.java
 (original)
+++ 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/IOUtilsTestCase.java
 Sat Mar 17 01:21:11 2012
@@ -17,7 +17,9 @@
 package org.apache.commons.io;
 
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
 import java.io.EOFException;
 import java.io.File;
 import java.io.FileInputStream;
@@ -73,10 +75,23 @@ public class IOUtilsTestCase extends Fil
             throw new RuntimeException("Can't run this test because " + 
"environment could not be built: "
                     + ioe.getMessage());
         }
+        // Create and init a byte array as input data
+        iarr = new byte[200];
+        Arrays.fill( iarr, (byte)-1);
+        for( int i=0; i< 80; i++){
+            iarr[i] = (byte) i;
+        }
+        carr = new char[200];
+        Arrays.fill( carr, (char)-1);
+        for( int i=0; i< 80; i++){
+            carr[i] = (char) i;
+        }
     }
 
     @Override
     public void tearDown() {
+        carr = null;
+        iarr = null;
         try {
             FileUtils.deleteDirectory(getTestDirectory());
         } catch (IOException ioe) {
@@ -718,4 +733,259 @@ public class IOUtilsTestCase extends Fil
         IOUtils.closeQuietly(input);
     }
 
+    // Tests from IO-305
+    
+    private byte[] iarr = null;
+    
+    public void testNoSkip() throws IOException {
+        ByteArrayInputStream is = null;
+        ByteArrayOutputStream os = null;
+        try {
+            // Create streams
+            is = new ByteArrayInputStream( iarr);
+            os = new ByteArrayOutputStream();
+
+            // Test our copy method 
+            assertEquals(100, IOUtils.copyLarge( is, os, 0, 100));
+            byte[] oarr = os.toByteArray();
+            
+            // check that output length is correct
+            assertEquals( 100, oarr.length );
+            // check that output data corresponds to input data
+            assertEquals( 1, oarr[1] );
+            assertEquals( 79, oarr[79] );
+            assertEquals( -1, oarr[80] );
+            
+        }
+        finally {
+            IOUtils.closeQuietly(is);
+            IOUtils.closeQuietly(os);
+        }
+    }
+
+    public void testSkip() throws IOException {
+        ByteArrayInputStream is = null;
+        ByteArrayOutputStream os = null;
+        try {
+            // Create streams
+            is = new ByteArrayInputStream( iarr);
+            os = new ByteArrayOutputStream();
+
+            // Test our copy method 
+            assertEquals(100, IOUtils.copyLarge( is, os, 10, 100));
+            byte[] oarr = os.toByteArray();
+            
+            // check that output length is correct
+            assertEquals( 100, oarr.length );
+            // check that output data corresponds to input data
+            assertEquals( 11, oarr[1] );
+            assertEquals( 79, oarr[69] );
+            assertEquals( -1, oarr[70] );
+            
+        }
+        finally {
+            IOUtils.closeQuietly(is);
+            IOUtils.closeQuietly(os);
+        }
+    }
+
+    public void testSkipInvalid() throws IOException {
+        ByteArrayInputStream is = null;
+        ByteArrayOutputStream os = null;
+        try {
+            // Create streams
+            is = new ByteArrayInputStream( iarr);
+            os = new ByteArrayOutputStream();
+
+            // Test our copy method 
+            IOUtils.copyLarge( is, os, 1000, 100);
+            fail( "Should have thrown EOFException");
+        }
+        catch( EOFException eofe){
+        }
+        finally {
+            IOUtils.closeQuietly(is);
+            IOUtils.closeQuietly(os);
+        }
+    }
+
+    public void testFullLength() throws IOException {
+        ByteArrayInputStream is = null;
+        ByteArrayOutputStream os = null;
+        try {
+            // Create streams
+            is = new ByteArrayInputStream( iarr);
+            os = new ByteArrayOutputStream();
+
+            // Test our copy method 
+            assertEquals(200, IOUtils.copyLarge( is, os, 0, -1));
+            byte[] oarr = os.toByteArray();
+            
+            // check that output length is correct
+            assertEquals( 200, oarr.length );
+            // check that output data corresponds to input data
+            assertEquals( 1, oarr[1] );
+            assertEquals( 79, oarr[79] );
+            assertEquals( -1, oarr[80] );
+            
+        }
+        finally {
+            IOUtils.closeQuietly(is);
+            IOUtils.closeQuietly(os);
+        }
+    }
+
+    public void testExtraLength() throws IOException {
+        ByteArrayInputStream is = null;
+        ByteArrayOutputStream os = null;
+        try {
+            // Create streams
+            is = new ByteArrayInputStream( iarr);
+            os = new ByteArrayOutputStream();
+
+            // Test our copy method
+            // for extra length, it reads till EOF
+            assertEquals(200, IOUtils.copyLarge( is, os, 0, 2000));
+            byte[] oarr = os.toByteArray();
+            
+            // check that output length is correct
+            assertEquals( 200, oarr.length );
+            // check that output data corresponds to input data
+            assertEquals( 1, oarr[1] );
+            assertEquals( 79, oarr[79] );
+            assertEquals( -1, oarr[80] );
+            
+        }
+        finally {
+            IOUtils.closeQuietly(is);
+            IOUtils.closeQuietly(os);
+        }
+    }
+
+    private char[] carr = null;
+
+    public void testCharNoSkip() throws IOException {
+        CharArrayReader is = null;
+        CharArrayWriter os = null;
+        try {
+            // Create streams
+            is = new CharArrayReader( carr);
+            os = new CharArrayWriter();
+
+            // Test our copy method 
+            assertEquals(100, IOUtils.copyLarge( is, os, 0, 100));
+            char[] oarr = os.toCharArray();
+            
+            // check that output length is correct
+            assertEquals( 100, oarr.length );
+            // check that output data corresponds to input data
+            assertEquals( 1, oarr[1] );
+            assertEquals( 79, oarr[79] );
+            assertEquals((char) -1, oarr[80] );
+            
+        }
+        finally {
+            IOUtils.closeQuietly(is);
+            IOUtils.closeQuietly(os);
+        }
+    }
+
+    public void testCharSkip() throws IOException {
+        CharArrayReader is = null;
+        CharArrayWriter os = null;
+        try {
+            // Create streams
+            is = new CharArrayReader( carr);
+            os = new CharArrayWriter();
+
+            // Test our copy method 
+            assertEquals(100, IOUtils.copyLarge( is, os, 10, 100));
+            char[] oarr = os.toCharArray();
+            
+            // check that output length is correct
+            assertEquals( 100, oarr.length );
+            // check that output data corresponds to input data
+            assertEquals( 11, oarr[1] );
+            assertEquals( 79, oarr[69] );
+            assertEquals((char) -1, oarr[70] );
+            
+        }
+        finally {
+            IOUtils.closeQuietly(is);
+            IOUtils.closeQuietly(os);
+        }
+    }
+
+    public void testCharSkipInvalid() throws IOException {
+        CharArrayReader is = null;
+        CharArrayWriter os = null;
+        try {
+            // Create streams
+            is = new CharArrayReader( carr);
+            os = new CharArrayWriter();
+
+            // Test our copy method 
+            IOUtils.copyLarge( is, os, 1000, 100);
+            fail( "Should have thrown EOFException");
+        }
+        catch( EOFException eofe){
+        }
+        finally {
+            IOUtils.closeQuietly(is);
+            IOUtils.closeQuietly(os);
+        }
+    }
+
+    public void testCharFullLength() throws IOException {
+        CharArrayReader is = null;
+        CharArrayWriter os = null;
+        try {
+            // Create streams
+            is = new CharArrayReader( carr);
+            os = new CharArrayWriter();
+
+            // Test our copy method 
+            assertEquals(200, IOUtils.copyLarge( is, os, 0, -1));
+            char[] oarr = os.toCharArray();
+            
+            // check that output length is correct
+            assertEquals( 200, oarr.length );
+            // check that output data corresponds to input data
+            assertEquals( 1, oarr[1] );
+            assertEquals( 79, oarr[79] );
+            assertEquals((char) -1, oarr[80] );
+            
+        }
+        finally {
+            IOUtils.closeQuietly(is);
+            IOUtils.closeQuietly(os);
+        }
+    }
+
+    public void testCharExtraLength() throws IOException {
+        CharArrayReader is = null;
+        CharArrayWriter os = null;
+        try {
+            // Create streams
+            is = new CharArrayReader( carr);
+            os = new CharArrayWriter();
+
+            // Test our copy method
+            // for extra length, it reads till EOF
+            assertEquals(200, IOUtils.copyLarge( is, os, 0, 2000));
+            char[] oarr = os.toCharArray();
+            
+            // check that output length is correct
+            assertEquals( 200, oarr.length );
+            // check that output data corresponds to input data
+            assertEquals( 1, oarr[1] );
+            assertEquals( 79, oarr[79] );
+            assertEquals((char) -1, oarr[80] );
+            
+        }
+        finally {
+            IOUtils.closeQuietly(is);
+            IOUtils.closeQuietly(os);
+        }
+    }
 }


Reply via email to