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
commit 44593a4db847870008c6bb7b60324b778b546762 Author: Gary D. Gregory <garydgreg...@gmail.com> AuthorDate: Fri Sep 12 10:45:04 2025 -0400 Sort members --- src/main/java/org/apache/commons/io/IOUtils.java | 84 ++++++++++----------- .../java/org/apache/commons/io/IOUtilsTest.java | 88 +++++++++++----------- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index a02a05092..cff8e4c23 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -1634,6 +1634,30 @@ public static long copyLarge(final Reader reader, final Writer writer, final lon return totalRead; } + /** + * Copies up to {@code size} bytes from the given {@link InputStream} into a new {@link UnsynchronizedByteArrayOutputStream}. + * + * @param input The {@link InputStream} to read; must not be {@code null}. + * @param limit The maximum number of bytes to read; must be {@code >= 0}. + * The actual bytes read are validated to equal {@code size}. + * @param bufferSize The buffer size of the output stream; must be {@code > 0}. + * @return a ByteArrayOutputStream containing the read bytes. + */ + private static UnsynchronizedByteArrayOutputStream copyToOutputStream( + final InputStream input, final long limit, final int bufferSize) throws IOException { + try (UnsynchronizedByteArrayOutputStream output = UnsynchronizedByteArrayOutputStream.builder() + .setBufferSize(bufferSize) + .get(); + InputStream boundedInput = BoundedInputStream.builder() + .setMaxCount(limit) + .setPropagateClose(false) + .setInputStream(input) + .get()) { + output.write(boundedInput); + return output; + } + } + /** * Fills the given array with 0s. * @@ -2687,30 +2711,6 @@ public static byte[] toByteArray(final InputStream input, final int size) throws return toByteArray(Objects.requireNonNull(input, "input")::read, size); } - /** - * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}. - * - * <p>This variant always allocates the whole requested array size, - * for a dynamic growing variant use {@link #toByteArray(InputStream, int, int)}, - * which enforces stricter memory usage constraints.</p> - * - * @param input the {@link InputStream} to read; must not be {@code null}. - * @param size the exact number of bytes to read; must be {@code >= 0} and {@code <= Integer.MAX_VALUE}. - * @return a new byte array of length {@code size}. - * @throws IllegalArgumentException if {@code size} is negative or does not fit into an int. - * @throws EOFException if the stream ends before {@code size} bytes are read. - * @throws IOException if an I/O error occurs while reading. - * @throws NullPointerException if {@code input} is {@code null}. - * @see #toByteArray(InputStream, int, int) - * @since 2.1 - */ - public static byte[] toByteArray(final InputStream input, final 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); - } - /** * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}. * @@ -2750,27 +2750,27 @@ public static byte[] toByteArray(final InputStream input, final int size, final } /** - * Copies up to {@code size} bytes from the given {@link InputStream} into a new {@link UnsynchronizedByteArrayOutputStream}. + * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}. * - * @param input The {@link InputStream} to read; must not be {@code null}. - * @param limit The maximum number of bytes to read; must be {@code >= 0}. - * The actual bytes read are validated to equal {@code size}. - * @param bufferSize The buffer size of the output stream; must be {@code > 0}. - * @return a ByteArrayOutputStream containing the read bytes. + * <p>This variant always allocates the whole requested array size, + * for a dynamic growing variant use {@link #toByteArray(InputStream, int, int)}, + * which enforces stricter memory usage constraints.</p> + * + * @param input the {@link InputStream} to read; must not be {@code null}. + * @param size the exact number of bytes to read; must be {@code >= 0} and {@code <= Integer.MAX_VALUE}. + * @return a new byte array of length {@code size}. + * @throws IllegalArgumentException if {@code size} is negative or does not fit into an int. + * @throws EOFException if the stream ends before {@code size} bytes are read. + * @throws IOException if an I/O error occurs while reading. + * @throws NullPointerException if {@code input} is {@code null}. + * @see #toByteArray(InputStream, int, int) + * @since 2.1 */ - private static UnsynchronizedByteArrayOutputStream copyToOutputStream( - final InputStream input, final long limit, final int bufferSize) throws IOException { - try (UnsynchronizedByteArrayOutputStream output = UnsynchronizedByteArrayOutputStream.builder() - .setBufferSize(bufferSize) - .get(); - InputStream boundedInput = BoundedInputStream.builder() - .setMaxCount(limit) - .setPropagateClose(false) - .setInputStream(input) - .get()) { - output.write(boundedInput); - return output; + public static byte[] toByteArray(final InputStream input, final 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); } /** diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 92925bdd7..2c1d92d89 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -128,6 +128,30 @@ public static void beforeAll() { IO.clear(); } + private static Stream<Arguments> testToByteArray_InputStream_Size_BufferSize_Succeeds() { + final byte[] data = new byte[1024]; + for (int i = 0; i < 1024; i++) { + data[i] = (byte) i; + } + return Stream.of( + // Eager reading + Arguments.of(data.clone(), 512, 1024), + // Incremental reading + Arguments.of(data.clone(), 1024, 512), + // No reading + Arguments.of(data.clone(), 0, 128)); + } + + static Stream<Arguments> testToByteArray_InputStream_Size_BufferSize_Throws() { + return Stream.of( + // Negative size + Arguments.of(-1, 128, IllegalArgumentException.class), + // Invalid buffer size + Arguments.of(0, 0, IllegalArgumentException.class), + // Huge size: should not cause OutOfMemoryError + Arguments.of(Integer.MAX_VALUE, 128, EOFException.class)); + } + @TempDir public File temporaryFolder; @@ -1291,6 +1315,8 @@ void testResourceToString_ExistingResourceAtRootPackage() throws Exception { assertEquals(fileSize, content.getBytes().length); } + // Tests from IO-305 + @Test void testResourceToString_ExistingResourceAtRootPackage_WithClassLoader() throws Exception { final long fileSize = TestResources.getFile("test-file-simple-utf8.bin").length(); @@ -1311,8 +1337,6 @@ void testResourceToString_ExistingResourceAtSubPackage() throws Exception { assertEquals(fileSize, content.getBytes().length); } - // Tests from IO-305 - @Test void testResourceToString_ExistingResourceAtSubPackage_WithClassLoader() throws Exception { final long fileSize = TestResources.getFile("FileUtilsTestDataCR.dat").length(); @@ -1625,6 +1649,24 @@ void testToByteArray_InputStream_Size() throws Exception { } } + @ParameterizedTest + @MethodSource + void testToByteArray_InputStream_Size_BufferSize_Succeeds(byte[] data, int size, int bufferSize) throws IOException { + final ByteArrayInputStream input = new ByteArrayInputStream(data); + final byte[] expected = Arrays.copyOf(data, size); + final byte[] actual = IOUtils.toByteArray(input, size, bufferSize); + assertArrayEquals(expected, actual); + } + + @ParameterizedTest + @MethodSource + void testToByteArray_InputStream_Size_BufferSize_Throws( + int size, int bufferSize, Class<? extends Exception> exceptionClass) throws IOException { + try (InputStream input = new NullInputStream(0)) { + assertThrows(exceptionClass, () -> IOUtils.toByteArray(input, size, bufferSize)); + } + } + @Test void testToByteArray_InputStream_SizeIllegal() throws Exception { try (InputStream fin = Files.newInputStream(testFilePath)) { @@ -1662,48 +1704,6 @@ void testToByteArray_InputStream_SizeZero() throws Exception { } } - @ParameterizedTest - @MethodSource - void testToByteArray_InputStream_Size_BufferSize_Succeeds(byte[] data, int size, int bufferSize) throws IOException { - final ByteArrayInputStream input = new ByteArrayInputStream(data); - final byte[] expected = Arrays.copyOf(data, size); - final byte[] actual = IOUtils.toByteArray(input, size, bufferSize); - assertArrayEquals(expected, actual); - } - - private static Stream<Arguments> testToByteArray_InputStream_Size_BufferSize_Succeeds() { - final byte[] data = new byte[1024]; - for (int i = 0; i < 1024; i++) { - data[i] = (byte) i; - } - return Stream.of( - // Eager reading - Arguments.of(data.clone(), 512, 1024), - // Incremental reading - Arguments.of(data.clone(), 1024, 512), - // No reading - Arguments.of(data.clone(), 0, 128)); - } - - @ParameterizedTest - @MethodSource - void testToByteArray_InputStream_Size_BufferSize_Throws( - int size, int bufferSize, Class<? extends Exception> exceptionClass) throws IOException { - try (InputStream input = new NullInputStream(0)) { - assertThrows(exceptionClass, () -> IOUtils.toByteArray(input, size, bufferSize)); - } - } - - static Stream<Arguments> testToByteArray_InputStream_Size_BufferSize_Throws() { - return Stream.of( - // Negative size - Arguments.of(-1, 128, IllegalArgumentException.class), - // Invalid buffer size - Arguments.of(0, 0, IllegalArgumentException.class), - // Huge size: should not cause OutOfMemoryError - Arguments.of(Integer.MAX_VALUE, 128, EOFException.class)); - } - @Test void testToByteArray_Reader() throws IOException { final String charsetName = UTF_8;