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 40b9af5 Add IOUtils.copy(URL, File) and copy(URL, OutputStream). 40b9af5 is described below commit 40b9af504c8c9cb313869786516348775443c086 Author: Gary Gregory <gardgreg...@gmail.com> AuthorDate: Sat Feb 6 14:31:44 2021 -0500 Add IOUtils.copy(URL, File) and copy(URL, OutputStream). --- src/changes/changes.xml | 6 +++ src/main/java/org/apache/commons/io/IOUtils.java | 47 ++++++++++++++++++++++ .../org/apache/commons/io/IOUtilsCopyTestCase.java | 34 ++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 7deebbc..95b0e42 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -175,6 +175,12 @@ The <action> type attribute can be add,update,fix,remove. <action dev="ggregory" type="add" due-to="Gary Gregory"> Make public and reuse IOUtils.EMPTY_BYTE_ARRAY. </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add IOUtils.copy(URL, File). + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add copy(URL, OutputStream). + </action> <!-- UPDATES --> <action dev="ggregory" type="update" due-to="Dependabot"> Update junit-jupiter from 5.6.2 to 5.7.0 #153. diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 4c34c01..1d3aa0e 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -25,6 +25,7 @@ import java.io.CharArrayWriter; import java.io.Closeable; import java.io.EOFException; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -1191,6 +1192,52 @@ public class IOUtils { } /** + * Copies bytes from a {@code URL} to an {@code OutputStream}. + * <p> + * This method buffers the input internally, so there is no need to use a {@code BufferedInputStream}. + * </p> + * <p> + * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. + * </p> + * + * @param url the {@code URL} to read. + * @param file the {@code OutputStream} to write. + * @return the number of bytes copied. + * @throws NullPointerException if the URL is {@code null}. + * @throws NullPointerException if the OutputStream is {@code null}. + * @throws IOException if an I/O error occurs. + * @since 2.9.0 + */ + public static long copy(final URL url, final File file) throws IOException { + try (FileOutputStream outputStream = new FileOutputStream(Objects.requireNonNull(file, "file"))) { + return copy(url, outputStream); + } + } + + /** + * Copies bytes from a {@code URL} to an {@code OutputStream}. + * <p> + * This method buffers the input internally, so there is no need to use a {@code BufferedInputStream}. + * </p> + * <p> + * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. + * </p> + * + * @param url the {@code URL} to read. + * @param outputStream the {@code OutputStream} to write. + * @return the number of bytes copied. + * @throws NullPointerException if the URL is {@code null}. + * @throws NullPointerException if the OutputStream is {@code null}. + * @throws IOException if an I/O error occurs. + * @since 2.9.0 + */ + public static long copy(final URL url, final OutputStream outputStream) throws IOException { + try (InputStream inputStream = Objects.requireNonNull(url, "url").openStream()) { + return copyLarge(inputStream, outputStream); + } + } + + /** * Copies bytes from a large (over 2GB) {@code InputStream} to an * {@code OutputStream}. * <p> diff --git a/src/test/java/org/apache/commons/io/IOUtilsCopyTestCase.java b/src/test/java/org/apache/commons/io/IOUtilsCopyTestCase.java index 1fec0ec..d15a9d9 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsCopyTestCase.java +++ b/src/test/java/org/apache/commons/io/IOUtilsCopyTestCase.java @@ -16,7 +16,9 @@ */ package org.apache.commons.io; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -27,7 +29,11 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; +import java.net.URL; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import org.apache.commons.io.input.NullInputStream; @@ -431,4 +437,32 @@ public class IOUtilsCopyTestCase { assertThrows(NullPointerException.class, () -> IOUtils.copy(reader, (Writer) null)); } + @Test + public void testCopy_URLToFile() throws Exception { + final String name = "/org/apache/commons/io/abitmorethan16k.txt"; + URL in = getClass().getResource(name); + assertNotNull(in, name); + + Path path = Files.createTempFile("testCopy_URLToFile", ".txt"); + try { + IOUtils.copy(in, path.toFile()); + + assertArrayEquals(Files.readAllBytes(Paths.get("src/test/resources" + name)), Files.readAllBytes(path)); + } finally { + Files.delete(path); + } + } + + @Test + public void testCopy_URLToOutputStream() throws Exception { + final String name = "/org/apache/commons/io/abitmorethan16k.txt"; + URL in = getClass().getResource(name); + assertNotNull(in, name); + + final ByteArrayOutputStream baout = new ByteArrayOutputStream(); + IOUtils.copy(in, baout); + + assertArrayEquals(Files.readAllBytes(Paths.get("src/test/resources" + name)), baout.toByteArray()); + } + }