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
The following commit(s) were added to refs/heads/master by this push: new f29c460b5 Add RandomAccessFileInputStream.copy(long, long, OutputStream) f29c460b5 is described below commit f29c460b5ef1ade718f6bc9a4ebfe95b999c657a Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Thu Jan 2 09:56:41 2025 -0500 Add RandomAccessFileInputStream.copy(long, long, OutputStream) --- src/changes/changes.xml | 1 + .../io/input/RandomAccessFileInputStream.java | 17 ++++++++++++ .../io/input/RandomAccessFileInputStreamTest.java | 32 ++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index c3b2a3027..bd169f69b 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -60,6 +60,7 @@ The <action> type attribute can be add,update,fix,remove. <action dev="ggregory" type="add" due-to="Gary Gregory">Add RandomAccessFileOutputStream.getRandomAccessFile().</action> <action dev="ggregory" type="add" due-to="Gary Gregory">Add ProxyInputStream.setReference(InputStream), was package-private setIn(InputStream).</action> <action dev="ggregory" type="add" due-to="Gary Gregory">Add ProxyOutputStream.setReference(OutputStream).</action> + <action dev="ggregory" type="add" due-to="Gary Gregory">Add RandomAccessFileInputStream.copy(long, long, OutputStream).</action> <!-- UPDATE --> <action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">Bump commons.bytebuddy.version from 1.15.10 to 1.15.11 #710.</action> </release> diff --git a/src/main/java/org/apache/commons/io/input/RandomAccessFileInputStream.java b/src/main/java/org/apache/commons/io/input/RandomAccessFileInputStream.java index 06005d9e1..312b56308 100644 --- a/src/main/java/org/apache/commons/io/input/RandomAccessFileInputStream.java +++ b/src/main/java/org/apache/commons/io/input/RandomAccessFileInputStream.java @@ -19,9 +19,11 @@ package org.apache.commons.io.input; import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.io.RandomAccessFile; import java.util.Objects; +import org.apache.commons.io.IOUtils; import org.apache.commons.io.build.AbstractOrigin; import org.apache.commons.io.build.AbstractStreamBuilder; @@ -188,6 +190,21 @@ public class RandomAccessFileInputStream extends AbstractInputStream { } } + /** + * Copies our bytes from the given starting position for a size to the output stream. + * + * @param pos Where to start copying. The offset position, measured in bytes from the beginning of the file, at which to set the file pointer. + * @param size The number of bytes to copy. + * @param os Where to copy. + * @return The number of bytes copied.. + * @throws IOException if {@code pos} is less than {@code 0} or if an I/O error occurs. + * @since 2.19.0 + */ + public long copy(final long pos, final long size, final OutputStream os) throws IOException { + randomAccessFile.seek(pos); + return IOUtils.copyLarge(this, os, 0, size); + } + /** * Gets the underlying file. * diff --git a/src/test/java/org/apache/commons/io/input/RandomAccessFileInputStreamTest.java b/src/test/java/org/apache/commons/io/input/RandomAccessFileInputStreamTest.java index cd01563ad..985be67d4 100644 --- a/src/test/java/org/apache/commons/io/input/RandomAccessFileInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/RandomAccessFileInputStreamTest.java @@ -34,6 +34,7 @@ import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import org.apache.commons.io.RandomAccessFileMode; +import org.apache.commons.io.output.ByteArrayOutputStream; import org.junit.jupiter.api.Test; /** @@ -150,6 +151,37 @@ public class RandomAccessFileInputStreamTest { } } + @Test + public void testCopy() throws IOException { + // @formatter:off + try (RandomAccessFileInputStream inputStream = RandomAccessFileInputStream.builder() + .setRandomAccessFile(createRandomAccessFile()) + .setCloseOnClose(true) + .get()) { + // @formatter:on + // A Test Line. + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + // 0 and 12 + assertEquals(12, inputStream.copy(0, 12, baos)); + assertArrayEquals("A Test Line.".getBytes(StandardCharsets.ISO_8859_1), baos.toByteArray()); + // 0 and 1 + baos.reset(); + assertEquals(1, inputStream.copy(0, 1, baos)); + assertArrayEquals("A".getBytes(StandardCharsets.ISO_8859_1), baos.toByteArray()); + // 11 and 1 + baos.reset(); + assertEquals(1, inputStream.copy(11, 1, baos)); + assertArrayEquals(".".getBytes(StandardCharsets.ISO_8859_1), baos.toByteArray()); + // 1 and 10 + baos.reset(); + assertEquals(10, inputStream.copy(1, 10, baos)); + assertArrayEquals(" Test Line".getBytes(StandardCharsets.ISO_8859_1), baos.toByteArray()); + // next + assertEquals('.', inputStream.read()); + } + } + } + @SuppressWarnings("resource") // instance variable access @Test public void testDeprecatedConstructorCloseOnCloseTrue() throws IOException {