You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2016/02/29 07:08:39 UTC

svn commit: r1732823 - in /directory/shared/trunk/util/src/main/java/org/apache/directory/api/util: FileUtils.java IOUtils.java

Author: elecharny
Date: Mon Feb 29 06:08:39 2016
New Revision: 1732823

URL: http://svn.apache.org/viewvc?rev=1732823&view=rev
Log:
Added some methods that are used by Studio

Modified:
    directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/FileUtils.java
    directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/IOUtils.java

Modified: directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/FileUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/FileUtils.java?rev=1732823&r1=1732822&r2=1732823&view=diff
==============================================================================
--- directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/FileUtils.java (original)
+++ directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/FileUtils.java Mon Feb 29 06:08:39 2016
@@ -28,6 +28,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.channels.FileChannel;
 import java.nio.charset.Charset;
 
 
@@ -50,6 +51,21 @@ public final class FileUtils
      */
     private static final char SYSTEM_SEPARATOR = File.separatorChar;
 
+    /**
+     * The number of bytes in a kilobyte.
+     */
+    public static final long ONE_KB = 1024;
+
+    /**
+     * The number of bytes in a megabyte.
+     */
+    public static final long ONE_MB = ONE_KB * ONE_KB;
+
+    /**
+     * The file copy buffer size (30 MB)
+     */
+    private static final long FILE_COPY_BUFFER_SIZE = ONE_MB * 30;
+
 
     /**
      * Creates a new instance of FileUtils.
@@ -278,6 +294,34 @@ public final class FileUtils
 
 
     /**
+     * Reads the contents of a file into a String. The file is always closed.
+     *
+     * @param file the file to read, must not be {@code null}
+     * @param encoding the encoding to use, {@code null} means platform default
+     * @return the file contents, never {@code null}
+     * @throws IOException in case of an I/O error
+     * @throws UnsupportedCharsetException
+     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
+     *             supported.
+     * @since 2.3
+     */
+    public static String readFileToString( File file, String encoding ) throws IOException
+    {
+        InputStream in = null;
+
+        try
+        {
+            in = openInputStream( file );
+            return IOUtils.toString( in, IOUtils.toCharset( encoding ) );
+        }
+        finally
+        {
+            IOUtils.closeQuietly( in );
+        }
+    }
+
+
+    /**
      * Opens a {@link FileInputStream} for the specified file, providing better
      * error messages than simply calling <code>new FileInputStream(file)</code>.
      * <p>
@@ -336,6 +380,24 @@ public final class FileUtils
     /**
      * Writes a String to a file creating the file if it does not exist.
      *
+     * NOTE: As from v1.3, the parent directories of the file will be created
+     * if they do not exist.
+     *
+     * @param file  the file to write
+     * @param data  the content to write to the file
+     * @param encoding  the encoding to use, {@code null} means platform default
+     * @throws IOException in case of an I/O error
+     * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
+     */
+    public static void writeStringToFile( File file, String data, String encoding ) throws IOException
+    {
+        writeStringToFile( file, data, IOUtils.toCharset( encoding ), false );
+    }
+
+
+    /**
+     * Writes a String to a file creating the file if it does not exist.
+     *
      * @param file  the file to write
      * @param data  the content to write to the file
      * @param encoding  the encoding to use, {@code null} means platform default
@@ -391,7 +453,7 @@ public final class FileUtils
             {
                 throw new IOException( "File '" + file + "' exists but is a directory" );
             }
-            
+
             if ( !file.canWrite() )
             {
                 throw new IOException( "File '" + file + "' cannot be written to" );
@@ -400,7 +462,7 @@ public final class FileUtils
         else
         {
             File parent = file.getParentFile();
-            
+
             if ( parent != null )
             {
                 if ( !parent.mkdirs() && !parent.isDirectory() )
@@ -409,11 +471,11 @@ public final class FileUtils
                 }
             }
         }
-        
+
         return new FileOutputStream( file, append );
     }
-    
-    
+
+
     /**
      * Returns a {@link File} representing the system temporary directory.
      *
@@ -421,8 +483,340 @@ public final class FileUtils
      *
      * @since 2.0
      */
-    public static File getTempDirectory() 
+    public static File getTempDirectory()
     {
         return new File( getTempDirectoryPath() );
     }
+
+
+    /**
+     * Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories.
+     * <p>
+     * The difference between File.delete() and this method are:
+     * <ul>
+     * <li>A directory to be deleted does not have to be empty.</li>
+     * <li>No exceptions are thrown when a file or directory cannot be deleted.</li>
+     * </ul>
+     *
+     * @param file  file or directory to delete, can be {@code null}
+     * @return {@code true} if the file or directory was deleted, otherwise
+     * {@code false}
+     *
+     * @since 1.4
+     */
+    public static boolean deleteQuietly( File file )
+    {
+        if ( file == null )
+        {
+            return false;
+        }
+
+        try
+        {
+            if ( file.isDirectory() )
+            {
+                cleanDirectory( file );
+            }
+        }
+        catch ( Exception ignored )
+        {
+        }
+
+        try
+        {
+            return file.delete();
+        }
+        catch ( Exception ignored )
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Copies a file to a new location preserving the file date.
+     * <p>
+     * This method copies the contents of the specified source file to the
+     * specified destination file. The directory holding the destination file is
+     * created if it does not exist. If the destination file exists, then this
+     * method will overwrite it.
+     * <p>
+     * <strong>Note:</strong> This method tries to preserve the file's last
+     * modified date/times using {@link File#setLastModified(long)}, however
+     * it is not guaranteed that the operation will succeed.
+     * If the modification operation fails, no indication is provided.
+     *
+     * @param srcFile  an existing file to copy, must not be {@code null}
+     * @param destFile  the new file, must not be {@code null}
+     *
+     * @throws NullPointerException if source or destination is {@code null}
+     * @throws IOException if source or destination is invalid
+     * @throws IOException if an IO error occurs during copying
+     * @throws IOException if the output file length is not the same as the input file length after the copy completes
+     * @see #copyFileToDirectory(File, File)
+     * @see #copyFile(File, File, boolean)
+     */
+    public static void copyFile( File srcFile, File destFile ) throws IOException
+    {
+        copyFile( srcFile, destFile, true );
+    }
+
+
+    /**
+     * Copies a file to a new location.
+     * <p>
+     * This method copies the contents of the specified source file
+     * to the specified destination file.
+     * The directory holding the destination file is created if it does not exist.
+     * If the destination file exists, then this method will overwrite it.
+     * <p>
+     * <strong>Note:</strong> Setting <code>preserveFileDate</code> to
+     * {@code true} tries to preserve the file's last modified
+     * date/times using {@link File#setLastModified(long)}, however it is
+     * not guaranteed that the operation will succeed.
+     * If the modification operation fails, no indication is provided.
+     *
+     * @param srcFile  an existing file to copy, must not be {@code null}
+     * @param destFile  the new file, must not be {@code null}
+     * @param preserveFileDate  true if the file date of the copy
+     *  should be the same as the original
+     *
+     * @throws NullPointerException if source or destination is {@code null}
+     * @throws IOException if source or destination is invalid
+     * @throws IOException if an IO error occurs during copying
+     * @throws IOException if the output file length is not the same as the input file length after the copy completes
+     * @see #copyFileToDirectory(File, File, boolean)
+     * @see #doCopyFile(File, File, boolean)
+     */
+    public static void copyFile( File srcFile, File destFile, boolean preserveFileDate ) throws IOException
+    {
+        if ( srcFile == null )
+        {
+            throw new NullPointerException( "Source must not be null" );
+        }
+
+        if ( destFile == null )
+        {
+            throw new NullPointerException( "Destination must not be null" );
+        }
+
+        if ( !srcFile.exists() )
+        {
+            throw new FileNotFoundException( "Source '" + srcFile + "' does not exist" );
+        }
+
+        if ( srcFile.isDirectory() )
+        {
+            throw new IOException( "Source '" + srcFile + "' exists but is a directory" );
+        }
+
+        if ( srcFile.getCanonicalPath().equals( destFile.getCanonicalPath() ) )
+        {
+            throw new IOException( "Source '" + srcFile + "' and destination '" + destFile + "' are the same" );
+        }
+
+        File parentFile = destFile.getParentFile();
+
+        if ( parentFile != null )
+        {
+            if ( !parentFile.mkdirs() && !parentFile.isDirectory() )
+            {
+                throw new IOException( "Destination '" + parentFile + "' directory cannot be created" );
+            }
+        }
+
+        if ( destFile.exists() && !destFile.canWrite() )
+        {
+            throw new IOException( "Destination '" + destFile + "' exists but is read-only" );
+        }
+
+        doCopyFile( srcFile, destFile, preserveFileDate );
+    }
+
+
+    /**
+     * Internal copy file method.
+     * This caches the original file length, and throws an IOException 
+     * if the output file length is different from the current input file length.
+     * So it may fail if the file changes size.
+     * It may also fail with "IllegalArgumentException: Negative size" if the input file is truncated part way
+     * through copying the data and the new file size is less than the current position.
+     *
+     * @param srcFile  the validated source file, must not be {@code null}
+     * @param destFile  the validated destination file, must not be {@code null}
+     * @param preserveFileDate  whether to preserve the file date
+     * @throws IOException if an error occurs
+     * @throws IOException if the output file length is not the same as the input file length after the copy completes
+     * @throws IllegalArgumentException "Negative size" if the file is truncated so that the size is less than the position
+     */
+    private static void doCopyFile( File srcFile, File destFile, boolean preserveFileDate ) throws IOException
+    {
+        if ( destFile.exists() && destFile.isDirectory() )
+        {
+            throw new IOException( "Destination '" + destFile + "' exists but is a directory" );
+        }
+
+        FileInputStream fis = null;
+        FileOutputStream fos = null;
+        FileChannel input = null;
+        FileChannel output = null;
+
+        try
+        {
+            fis = new FileInputStream( srcFile );
+            fos = new FileOutputStream( destFile );
+            input = fis.getChannel();
+            output = fos.getChannel();
+            long size = input.size(); // TODO See IO-386
+            long pos = 0;
+            long count = 0;
+
+            while ( pos < size )
+            {
+                long remain = size - pos;
+                count = remain > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : remain;
+                long bytesCopied = output.transferFrom( input, pos, count );
+
+                if ( bytesCopied == 0 )
+                { // IO-385 - can happen if file is truncated after caching the size
+                    break; // ensure we don't loop forever
+                }
+
+                pos += bytesCopied;
+            }
+        }
+        finally
+        {
+            IOUtils.closeQuietly( output, fos, input, fis );
+        }
+
+        long srcLen = srcFile.length(); // TODO See IO-386
+        long dstLen = destFile.length(); // TODO See IO-386
+
+        if ( srcLen != dstLen )
+        {
+            throw new IOException( "Failed to copy full contents from '"
+                + srcFile + "' to '" + destFile + "' Expected length: " + srcLen + " Actual: " + dstLen );
+        }
+
+        if ( preserveFileDate )
+        {
+            destFile.setLastModified( srcFile.lastModified() );
+        }
+    }
+
+
+    /**
+     * Writes a byte array to a file creating the file if it does not exist.
+     * <p>
+     * NOTE: As from v1.3, the parent directories of the file will be created
+     * if they do not exist.
+     *
+     * @param file  the file to write to
+     * @param data  the content to write to the file
+     * @throws IOException in case of an I/O erroe
+     * @since 1.1
+     */
+    public static void writeByteArrayToFile( final File file, final byte[] data ) throws IOException
+    {
+        writeByteArrayToFile( file, data, false );
+    }
+
+
+    /**
+     * Writes a byte array to a file creating the file if it does not exist.
+     *
+     * @param file  the file to write to
+     * @param data  the content to write to the file
+     * @param append if {@code true}, then bytes will be added to the
+     * end of the file rather than overwriting
+     * @throws IOException in case of an I/O error
+     * @since 2.1
+     */
+    public static void writeByteArrayToFile( File file, byte[] data, boolean append ) throws IOException
+    {
+        writeByteArrayToFile( file, data, 0, data.length, append );
+    }
+
+
+    /**
+     * Writes {@code len} bytes from the specified byte array starting
+     * at offset {@code off} to a file, creating the file if it does
+     * not exist.
+     *
+     * @param file  the file to write to
+     * @param data  the content to write to the file
+     * @param off   the start offset in the data
+     * @param len   the number of bytes to write
+     * @param append if {@code true}, then bytes will be added to the
+     * end of the file rather than overwriting
+     * @throws IOException in case of an I/O error
+     * @since 2.5
+     */
+    public static void writeByteArrayToFile( File file, byte[] data, int off, int len, boolean append ) throws IOException
+    {
+        OutputStream out = null;
+        
+        try
+        {
+            out = openOutputStream( file, append );
+            out.write( data, off, len );
+            out.close(); // don't swallow close Exception if copy completes normally
+        }
+        finally
+        {
+            IOUtils.closeQuietly( out );
+        }
+    }
+
+    
+    /**
+     * Reads the contents of a file into a byte array.
+     * The file is always closed.
+     *
+     * @param file  the file to read, must not be {@code null}
+     * @return the file contents, never {@code null}
+     * @throws IOException in case of an I/O error
+     * @since 1.1
+     */
+    public static byte[] readFileToByteArray( File file ) throws IOException 
+    {
+        InputStream in = null;
+        
+        try 
+        {
+            in = openInputStream( file );
+            return IOUtils.toByteArray( in, file.length() );
+        } 
+        finally 
+        {
+            IOUtils.closeQuietly( in );
+        }
+    }
+
+    
+    /**
+     * Opens a {@link FileOutputStream} for the specified file, checking and
+     * creating the parent directory if it does not exist.
+     * <p>
+     * At the end of the method either the stream will be successfully opened,
+     * or an exception will have been thrown.
+     * <p>
+     * The parent directory will be created if it does not exist.
+     * The file will be created if it does not exist.
+     * An exception is thrown if the file object exists but is a directory.
+     * An exception is thrown if the file exists but cannot be written to.
+     * An exception is thrown if the parent directory cannot be created.
+     *
+     * @param file  the file to open for output, must not be {@code null}
+     * @return a new {@link FileOutputStream} for the specified file
+     * @throws IOException if the file object is a directory
+     * @throws IOException if the file cannot be written to
+     * @throws IOException if a parent directory needs creating but that fails
+     * @since 1.3
+     */
+    public static FileOutputStream openOutputStream( File file ) throws IOException 
+    {
+        return openOutputStream( file, false );
+    }
 }

Modified: directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/IOUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/IOUtils.java?rev=1732823&r1=1732822&r2=1732823&view=diff
==============================================================================
--- directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/IOUtils.java (original)
+++ directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/IOUtils.java Mon Feb 29 06:08:39 2016
@@ -122,6 +122,55 @@ public final class IOUtils
      * }
      * </pre>
      * 
+     * @param closeables the objects to close, may be null or already closed
+     * @since 2.5
+     */
+    public static void closeQuietly( Closeable... closeables )
+    {
+        if ( closeables == null )
+        {
+            return;
+        }
+
+        for ( Closeable closeable : closeables )
+        {
+            closeQuietly( closeable );
+        }
+    }
+
+
+    /**
+     * Closes a <code>Closeable</code> unconditionally.
+     * <p>
+     * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. This is typically used in
+     * finally blocks.
+     * <p>
+     * Example code:
+     * 
+     * <pre>
+     * Closeable closeable = null;
+     * try {
+     *     closeable = new FileReader(&quot;foo.txt&quot;);
+     *     // process closeable
+     *     closeable.close();
+     * } catch (Exception e) {
+     *     // error handling
+     * } finally {
+     *     IOUtils.closeQuietly(closeable);
+     * }
+     * </pre>
+     * 
+     * Closing all streams:
+     * 
+     * <pre>
+     * try {
+     *     return IOUtils.copy(inputStream, outputStream);
+     * } finally {
+     *     IOUtils.closeQuietly(inputStream);
+     *     IOUtils.closeQuietly(outputStream);
+     * }
+     * </pre>
+     * 
      * @param closeable
      *            the objects to close, may be null or already closed
      * @since 2.0
@@ -178,6 +227,19 @@ public final class IOUtils
 
 
     /**
+     * Returns a Charset for the named charset. If the name is null, return the default Charset.
+     * 
+     * @param charset The name of the requested charset, may be null.
+     * @return a Charset for the named charset
+     * @throws UnsupportedCharsetException If the named charset is unavailable
+     */
+    public static Charset toCharset( String charset )
+    {
+        return charset == null ? Charset.defaultCharset() : Charset.forName( charset );
+    }
+
+
+    /**
      * Copies bytes from an <code>InputStream</code> to chars on a
      * <code>Writer</code> using the specified character encoding.
      * <p>
@@ -230,6 +292,64 @@ public final class IOUtils
         return ( int ) count;
     }
 
+    
+    /**
+     * Copies bytes from an <code>InputStream</code> to an
+     * <code>OutputStream</code>.
+     * <p>
+     * This method buffers the input internally, so there is no need to use a
+     * <code>BufferedInputStream</code>.
+     * <p>
+     * Large streams (over 2GB) will return a bytes copied value of
+     * <code>-1</code> after the copy has completed since the correct
+     * number of bytes cannot be returned as an int. For large streams
+     * use the <code>copyLarge(InputStream, OutputStream)</code> method.
+     *
+     * @param input  the <code>InputStream</code> to read from
+     * @param output  the <code>OutputStream</code> to write to
+     * @return the number of bytes copied, or -1 if &gt; Integer.MAX_VALUE
+     * @throws NullPointerException if the input or output is null
+     * @throws IOException if an I/O error occurs
+     * @since 1.1
+     */
+    public static int copy( InputStream input, OutputStream output ) throws IOException 
+    {
+        long count = copyLarge( input, output );
+        
+        if ( count > Integer.MAX_VALUE ) 
+        {
+            return -1;
+        }
+        
+        return ( int ) count;
+    }
+    
+    
+    /**
+     * Copies bytes from an <code>InputStream</code> to an <code>OutputStream</code> using an internal buffer of the
+     * given size.
+     * <p>
+     * This method buffers the input internally, so there is no need to use a <code>BufferedInputStream</code>.
+     * <p>
+     *
+     * @param input
+     *            the <code>InputStream</code> to read from
+     * @param output
+     *            the <code>OutputStream</code> to write to
+     * @param bufferSize
+     *            the bufferSize used to copy from the input to the output
+     * @return the number of bytes copied
+     * @throws NullPointerException
+     *             if the input or output is null
+     * @throws IOException
+     *             if an I/O error occurs
+     * @since 2.5
+     */
+    public static long copy( InputStream input, OutputStream output, int bufferSize ) throws IOException 
+    {
+        return copyLarge( input, output, new byte[bufferSize] );
+    }
+
 
     /**
      * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
@@ -250,6 +370,59 @@ public final class IOUtils
     {
         return copyLarge( input, output, new char[DEFAULT_BUFFER_SIZE] );
     }
+    
+    
+    /**
+     * Copies bytes from a large (over 2GB) <code>InputStream</code> to an
+     * <code>OutputStream</code>.
+     * <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
+     * @return the number of bytes copied
+     * @throws NullPointerException if the input or output is null
+     * @throws IOException if an I/O error occurs
+     * @since 1.3
+     */
+    public static long copyLarge( InputStream input, OutputStream output ) throws IOException 
+    {
+        return copy( input, output, DEFAULT_BUFFER_SIZE );
+    }
+
+    
+    /**
+     * Copies bytes from a large (over 2GB) <code>InputStream</code> to an
+     * <code>OutputStream</code>.
+     * <p>
+     * This method uses the provided buffer, so there is no need to use a
+     * <code>BufferedInputStream</code>.
+     * <p>
+     *
+     * @param input  the <code>InputStream</code> to read from
+     * @param output  the <code>OutputStream</code> to write to
+     * @param buffer the buffer to use for the copy
+     * @return the number of bytes copied
+     * @throws NullPointerException if the input or output is null
+     * @throws IOException if an I/O error occurs
+     * @since 2.2
+     */
+    public static long copyLarge( InputStream input, OutputStream output, byte[] buffer ) throws IOException 
+    {
+        long count = 0;
+        int n = 0;
+        
+        while ( EOF != ( n = input.read( buffer ) ) ) 
+        {
+            output.write( buffer, 0, n );
+            count += n;
+        }
+        
+        return count;
+    }
 
 
     /**
@@ -280,8 +453,8 @@ public final class IOUtils
 
         return count;
     }
-    
-    
+
+
     /**
      * Writes chars from a <code>String</code> to bytes on an
      * <code>OutputStream</code> using the specified character encoding.
@@ -295,11 +468,81 @@ public final class IOUtils
      * @throws IOException if an I/O error occurs
      * @since 2.3
      */
-    public static void write( String data, OutputStream output, Charset encoding ) throws IOException 
+    public static void write( String data, OutputStream output, Charset encoding ) throws IOException
     {
-        if ( data != null ) 
+        if ( data != null )
         {
             output.write( data.getBytes( toCharset( encoding ) ) );
         }
     }
+
+
+    /**
+     * Gets 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 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 = input.read( data, offset, size - offset );
+
+        while ( offset < size && ( readed != EOF ) )
+        {
+            offset += readed;
+            readed = input.read( data, offset, size - offset );
+        }
+
+        if ( offset != size )
+        {
+            throw new IOException( "Unexpected readed size. current: " + offset + ", excepted: " + size );
+        }
+
+        return data;
+    }
+    
+    
+    /**
+     * Gets 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 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 );
+    }
 }