You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2011/04/10 13:43:51 UTC

svn commit: r1090783 - in /commons/proper/io/trunk/src: changes/changes.xml main/java/org/apache/commons/io/FileUtils.java main/java/org/apache/commons/io/IOUtils.java test/java/org/apache/commons/io/IOUtilsTestCase.java

Author: sebb
Date: Sun Apr 10 11:43:51 2011
New Revision: 1090783

URL: http://svn.apache.org/viewvc?rev=1090783&view=rev
Log:
IO-251 Add new read method "toByteArray" to handle InputStream with known size.

Modified:
    commons/proper/io/trunk/src/changes/changes.xml
    commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java
    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/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/changes/changes.xml?rev=1090783&r1=1090782&r2=1090783&view=diff
==============================================================================
--- commons/proper/io/trunk/src/changes/changes.xml (original)
+++ commons/proper/io/trunk/src/changes/changes.xml Sun Apr 10 11:43:51 2011
@@ -40,10 +40,15 @@ The <action> type attribute can be add,u
 
   <body>
     <release version="1.4" date="Not yet released">
+
+      <action dev="sebb" type="add" issue="IO-251" due-to="Marco Albini">
+        Add new read method "toByteArray" to handle InputStream with known size.
+      </action>
       <action dev="sebb" type="fix" issue="IO-263" due-to="Gil Adam">
         FileSystemUtils.freeSpaceKb throws exception for Windows volumes with no visible files.
         Improve coverage by also looking for hidden files.
       </action>
+
     </release>
 
     <release version="1.3.2" date="2007-Jul-02">

Modified: commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java?rev=1090783&r1=1090782&r2=1090783&view=diff
==============================================================================
--- commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java (original)
+++ commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java Sun Apr 10 11:43:51 2011
@@ -1428,7 +1428,7 @@ public class FileUtils {
         InputStream in = null;
         try {
             in = openInputStream(file);
-            return IOUtils.toByteArray(in);
+            return IOUtils.toByteArray(in, file.length());
         } finally {
             IOUtils.closeQuietly(in);
         }

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=1090783&r1=1090782&r2=1090783&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 Sun Apr 10 11:43:51 2011
@@ -133,7 +133,7 @@ public class IOUtils {
     // Allocated in the skip method if necessary.
     private static char[] SKIP_CHAR_BUFFER;
     private static byte[] SKIP_BYTE_BUFFER;
-    
+
     /**
      * Instances should NOT be constructed in standard programming.
      */
@@ -361,6 +361,67 @@ public class IOUtils {
     }
 
     /**
+     * Get contents of an <code>InputStream</code> as a <code>byte[]</code>.
+     * Use this method instead of <code>toByteArray(InputStream)</code>
+     * when <code>InputStream</code> size is known.
+     * <b>NOTE:</b> the method checks that the length can safely be cast to an int without truncation
+     * before using {@link IOUtils#toByteArray(java.io.InputStream, int)} to read into the byte array.
+     * (Arrays can have no more than Integer.MAX_VALUE entries anyway)
+     * 
+     * @param input the <code>InputStream</code> to read from
+     * @param size the size of <code>InputStream</code>
+     * @return the requested byte array
+     * @throws IOException if an I/O error occurs or <code>InputStream</code> size differ from parameter size
+     * @throws IllegalArgumentException if size is less than zero or size is greater than Integer.MAX_VALUE
+     * @see IOUtils#toByteArray(java.io.InputStream, int)
+     * @since Commons IO 2.1
+     */
+    public static byte[] toByteArray(InputStream input, long size) throws IOException {
+
+      if(size > Integer.MAX_VALUE) {
+          throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);
+      }
+
+      return toByteArray(input, (int) size);
+    }
+
+    /** 
+     * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
+     * Use this method instead of <code>toByteArray(InputStream)</code>
+     * when <code>InputStream</code> size is known
+     * @param input the <code>InputStream</code> to read from
+     * @param size the size of <code>InputStream</code>
+     * @return the requested byte array
+     * @throws IOException if an I/O error occurs or <code>InputStream</code> size differ from parameter size
+     * @throws IllegalArgumentException if size is less than zero
+     * @since Commons IO 2.1
+     */
+    public static byte[] toByteArray(InputStream input, int size) throws IOException {
+
+        if(size < 0) {
+            throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);
+        }
+        
+        if(size == 0) {
+            return new byte[0];
+        }
+
+        byte[] data = new byte[size];
+        int offset = 0;
+        int readed;
+
+        while(offset < size && (readed = input.read(data, offset, (size - offset))) != -1) {
+            offset += readed;
+        }
+
+        if(offset != size) {
+            throw new IOException("Unexpected readed size. current: " + offset + ", excepted: " + size);
+        }
+
+        return data;
+    }
+
+    /**
      * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
      * using the default character encoding of the platform.
      * <p>

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=1090783&r1=1090782&r2=1090783&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 Sun Apr 10 11:43:51 2011
@@ -223,6 +223,82 @@ public class IOUtilsTestCase extends Fil
         }
     }
 
+    public void testInputStreamToByteArray_Size()
+        throws Exception {
+        FileInputStream fin = new FileInputStream( m_testFile );
+        try {
+            byte[] out = IOUtils.toByteArray( fin, m_testFile.length());
+            assertNotNull( out );
+            assertTrue( "Not all bytes were read", fin.available() == 0 );
+            assertTrue( "Wrong output size: out.length=" + out.length +
+                        "!=" + FILE_SIZE, out.length == FILE_SIZE );
+            assertEqualContent( out, m_testFile );
+        } finally {
+            fin.close();
+        }
+    }
+
+    public void testInputStreamToByteArray_NegativeSize()
+        throws Exception {
+        FileInputStream fin = new FileInputStream( m_testFile );
+
+        try {
+            IOUtils.toByteArray( fin, -1);
+            fail("IllegalArgumentException excepted");
+        } catch (IllegalArgumentException exc) {
+            assertTrue("Exception message does not start with \"Size must be equal or greater than zero\"",
+                       exc.getMessage().startsWith("Size must be equal or greater than zero"));
+        } finally {
+            fin.close();
+        }
+
+    }
+
+    public void testInputStreamToByteArray_ZeroSize()
+        throws Exception {
+        FileInputStream fin = new FileInputStream( m_testFile );
+
+        try {
+            byte[] out = IOUtils.toByteArray( fin, 0);
+            assertNotNull("Out cannot be null", out);
+            assertTrue("Out length must be 0", out.length == 0);
+        } finally {
+            fin.close();
+        }
+    }
+
+    public void testInputStreamToByteArray_IllegalSize()
+        throws Exception {
+        FileInputStream fin = new FileInputStream( m_testFile );
+
+        try {
+            IOUtils.toByteArray( fin, m_testFile.length() + 1);
+            fail("IOException excepted");
+        } catch (IOException exc) {
+            assertTrue("Exception message does not start with \"Unexpected readed size\"",
+                       exc.getMessage().startsWith("Unexpected readed size"));
+        } finally {
+            fin.close();
+        }
+
+    }
+
+    public void testInputStreamToByteArray_LongSize()
+        throws Exception {
+        FileInputStream fin = new FileInputStream( m_testFile );
+
+        try {
+            IOUtils.toByteArray( fin, (long) Integer.MAX_VALUE + 1);
+            fail("IOException excepted");
+        } catch (IllegalArgumentException exc) {
+            assertTrue("Exception message does not start with \"Size cannot be greater than Integer max value\"",
+                       exc.getMessage().startsWith("Size cannot be greater than Integer max value"));
+        } finally {
+            fin.close();
+        }
+
+    }
+
     public void testInputStreamToBufferedInputStream() throws Exception {
         FileInputStream fin = new FileInputStream(m_testFile);
         try {