Skip to content

Commit

Permalink
Add IOUtils.copy(URL, File) and copy(URL, OutputStream).
Browse files Browse the repository at this point in the history
  • Loading branch information
Gary Gregory committed Feb 6, 2021
1 parent 1d39856 commit 40b9af5
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/changes/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
47 changes: 47 additions & 0 deletions src/main/java/org/apache/commons/io/IOUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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;
Expand Down Expand Up @@ -1190,6 +1191,52 @@ public static int copy(final Reader reader, final Writer writer) throws IOExcept
return (int) count;
}

/**
* 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}.
Expand Down
34 changes: 34 additions & 0 deletions src/test/java/org/apache/commons/io/IOUtilsCopyTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -27,7 +29,11 @@
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;
Expand Down Expand Up @@ -431,4 +437,32 @@ public void testCopy_readerToWriter_nullOut() {
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());
}

}

0 comments on commit 40b9af5

Please sign in to comment.