Author: ggregory Date: Thu Nov 29 16:00:37 2012 New Revision: 1415223 URL: http://svn.apache.org/viewvc?rev=1415223&view=rev Log: <action issue="IO-358" dev="ggregory" type="add" due-to="yukoba">Add IOUtils.read and readFully(ReadableByteChannel, ByteBuffer buffer).</action>
Modified: 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/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/changes/changes.xml?rev=1415223&r1=1415222&r2=1415223&view=diff ============================================================================== --- commons/proper/io/trunk/src/changes/changes.xml (original) +++ commons/proper/io/trunk/src/changes/changes.xml Thu Nov 29 16:00:37 2012 @@ -47,7 +47,10 @@ The <action> type attribute can be add,u <body> <!-- The release date is the date RC is cut --> <release version="2.5" date="201?-??-??" description="New features and bug fixes."> - <action issue="IO-358" dev="ggregory" type="fix" due-to="mortenh"> + <action issue="IO-358" dev="ggregory" type="add" due-to="yukoba"> + Add IOUtils.read and readFully(ReadableByteChannel, ByteBuffer buffer). + </action> + <action issue="IO-357" dev="ggregory" type="fix" due-to="mortenh"> [Tailer] InterruptedException while the thead is sleeping is silently ignored </action> <action issue="IO-353" dev="ggregory" type="add" due-to="ggregory"> 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=1415223&r1=1415222&r2=1415223&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 Thu Nov 29 16:00:37 2012 @@ -38,6 +38,8 @@ import java.net.Socket; import java.net.URI; import java.net.URL; import java.net.URLConnection; +import java.nio.ByteBuffer; +import java.nio.channels.ReadableByteChannel; import java.nio.channels.Selector; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; @@ -2538,6 +2540,30 @@ public class IOUtils { } /** + * Reads bytes from a ReadableByteChannel. + * <p> + * This implementation guarantees that it will read as many bytes + * as possible before giving up; this may not always be the case for + * subclasses of {@link ReadableByteChannel}. + * + * @param input the byte channel to read + * @param buffer byte buffer destination + * @return the actual length read; may be less than requested if EOF was reached + * @throws IOException if a read error occurs + * @since 2.5 + */ + public static int read(ReadableByteChannel input, ByteBuffer buffer) throws IOException { + int length = buffer.remaining(); + while (buffer.remaining() > 0) { + int count = input.read(buffer); + if (EOF == count) { // EOF + break; + } + } + return length - buffer.remaining(); + } + + /** * Read the requested number of characters or fail if there are not enough left. * <p> * This allows for the possibility that {@link Reader#read(char[], int, int)} may @@ -2618,4 +2644,25 @@ public class IOUtils { public static void readFully(InputStream input, byte[] buffer) throws IOException { readFully(input, buffer, 0, buffer.length); } + + /** + * Reads the requested number of bytes or fail if there are not enough left. + * <p> + * This allows for the possibility that {@link ReadableByteChannel#read(ByteBuffer)} may + * not read as many bytes as requested (most likely because of reaching EOF). + * + * @param input the byte channel to read + * @param buffer byte buffer destination + * + * @throws IOException if there is a problem reading the file + * @throws EOFException if the number of bytes read was incorrect + * @since 2.5 + */ + public static void readFully(ReadableByteChannel input, ByteBuffer buffer) throws IOException { + int expected = buffer.remaining(); + int actual = read(input, buffer); + if (actual != expected) { + throw new EOFException("Length to read: " + expected + " actual: " + actual); + } + } } 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=1415223&r1=1415222&r2=1415223&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 Thu Nov 29 16:00:37 2012 @@ -38,6 +38,8 @@ import java.net.Socket; import java.net.URI; import java.net.URL; import java.net.URLConnection; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; import java.nio.channels.Selector; import java.util.Arrays; import java.util.List; @@ -791,6 +793,54 @@ public class IOUtilsTestCase extends Fil } + public void testRead_ReadableByteChannel() throws Exception { + ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE); + final FileInputStream fileInputStream = new FileInputStream(m_testFile); + FileChannel input = fileInputStream.getChannel(); + try { + assertEquals(FILE_SIZE, IOUtils.read(input, buffer)); + assertEquals(0, IOUtils.read(input, buffer)); + assertEquals(0, buffer.remaining()); + assertEquals(0, input.read(buffer)); + buffer.clear(); + try { + IOUtils.readFully(input, buffer); + fail("Should have failed with EOFxception"); + } catch (EOFException expected) { + // expected + } + } finally { + IOUtils.closeQuietly(input); + IOUtils.closeQuietly(fileInputStream); + }} + + public void testReadFully_ReadableByteChannel() throws Exception { + ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE); + final FileInputStream fileInputStream = new FileInputStream(m_testFile); + FileChannel input = fileInputStream.getChannel(); + try { + IOUtils.readFully(input, buffer); + assertEquals(FILE_SIZE, buffer.position()); + assertEquals(0, buffer.remaining()); + assertEquals(0, input.read(buffer)); + IOUtils.readFully(input, buffer); + assertEquals(FILE_SIZE, buffer.position()); + assertEquals(0, buffer.remaining()); + assertEquals(0, input.read(buffer)); + IOUtils.readFully(input, buffer); + buffer.clear(); + try { + IOUtils.readFully(input, buffer); + fail("Should have failed with EOFxception"); + } catch (EOFException expected) { + // expected + } + } finally { + IOUtils.closeQuietly(input); + IOUtils.closeQuietly(fileInputStream); + } + } + public void testReadReader() throws Exception { final int size = 1027;