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 4810d9c FileUtils.copyURLToFile should create target parent
directories and overwrite target file #319.
4810d9c is described below
commit 4810d9c57276b584942cf93ae297f10a12ab128c
Author: Gary Gregory <[email protected]>
AuthorDate: Sun Jan 30 09:16:42 2022 -0500
FileUtils.copyURLToFile should create target parent directories and
overwrite target file #319.
- Based on PR #39 but different.
- New assert method leaks input stream; this bug was copied from
existing code into a new method.
- Use NIO.
- Tests don't need to schedule files for deletion on exit when JUnit
already manages the directory.
---
src/changes/changes.xml | 3 +
src/main/java/org/apache/commons/io/FileUtils.java | 4 +-
.../java/org/apache/commons/io/FileUtilsTest.java | 96 +++++++++-------------
.../io/file/PathUtilsContentEqualsTest.java | 3 -
4 files changed, 47 insertions(+), 59 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 53ef159..5aaca08 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -135,6 +135,9 @@ The <action> type attribute can be add,update,fix,remove.
<action dev="ggregory" type="fix" due-to="Gary Gregory">
WriterOutputStream maps null Charset, Charset name, and CharsetEncoder
name to the platform default instead of throwing a NullPointerException.
</action>
+ <action dev="ggregory" type="fix" due-to="Chad Wilson, Gary Gregory">
+ FileUtils.copyURLToFile should create target parent directories and
overwrite target file #319.
+ </action>
<!-- ADD -->
<action issue="IO-726" dev="ggregory" type="fix" due-to="shollander,
Gary Gregory">
Add MemoryMappedFileInputStream #215.
diff --git a/src/main/java/org/apache/commons/io/FileUtils.java
b/src/main/java/org/apache/commons/io/FileUtils.java
index 0f18096..339a814 100644
--- a/src/main/java/org/apache/commons/io/FileUtils.java
+++ b/src/main/java/org/apache/commons/io/FileUtils.java
@@ -1060,7 +1060,9 @@ public class FileUtils {
*/
public static void copyURLToFile(final URL source, final File destination)
throws IOException {
try (final InputStream stream = source.openStream()) {
- Files.copy(stream, destination.toPath());
+ final Path path = destination.toPath();
+ PathUtils.createParentDirectories(path);
+ Files.copy(stream, path, StandardCopyOption.REPLACE_EXISTING);
}
}
diff --git a/src/test/java/org/apache/commons/io/FileUtilsTest.java
b/src/test/java/org/apache/commons/io/FileUtilsTest.java
index 1cf9026..1e75d3f 100644
--- a/src/test/java/org/apache/commons/io/FileUtilsTest.java
+++ b/src/test/java/org/apache/commons/io/FileUtilsTest.java
@@ -167,6 +167,15 @@ public class FileUtilsTest extends AbstractTempDirTest {
private long testFile2Size;
+ private void assertContentMatchesAfterCopyURLToFileFor(final String
resourceName, final File destination) throws IOException {
+ FileUtils.copyURLToFile(getClass().getResource(resourceName),
destination);
+
+ try (InputStream fis = Files.newInputStream(destination.toPath());
+ InputStream expected =
getClass().getResourceAsStream(resourceName)) {
+ assertTrue(IOUtils.contentEquals(expected, fis), "Content is not
equal.");
+ }
+ }
+
private void backDateFile10Minutes(final File testFile) throws IOException
{
final long mins10 = 1000 * 60 * 10;
final long lastModified1 = getLastModifiedMillis(testFile);
@@ -616,21 +625,18 @@ public class FileUtilsTest extends AbstractTempDirTest {
// Different files
final File objFile1 =
new File(tempDirFile, getName() + ".object");
- objFile1.deleteOnExit();
FileUtils.copyURLToFile(
getClass().getResource("/java/lang/Object.class"),
objFile1);
final File objFile1b =
new File(tempDirFile, getName() + ".object2");
- objFile1.deleteOnExit();
FileUtils.copyURLToFile(
getClass().getResource("/java/lang/Object.class"),
objFile1b);
final File objFile2 =
new File(tempDirFile, getName() + ".collection");
- objFile2.deleteOnExit();
FileUtils.copyURLToFile(
getClass().getResource("/java/util/Collection.class"),
objFile2);
@@ -650,8 +656,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
assertTrue(FileUtils.contentEquals(file, file2));
}
- // toFiles
-
@Test
public void testContentEqualsIgnoreEOL() throws Exception {
// Non-existent files
@@ -672,15 +676,12 @@ public class FileUtilsTest extends AbstractTempDirTest {
// Different files
final File tfile1 = new File(tempDirFile, getName() + ".txt1");
- tfile1.deleteOnExit();
FileUtils.write(tfile1, "123\r");
final File tfile2 = new File(tempDirFile, getName() + ".txt2");
- tfile1.deleteOnExit();
FileUtils.write(tfile2, "123\n");
final File tfile3 = new File(tempDirFile, getName() + ".collection");
- tfile3.deleteOnExit();
FileUtils.write(tfile3, "123\r\n2");
assertTrue(FileUtils.contentEqualsIgnoreEOL(tfile1, tfile1, null));
@@ -839,7 +840,25 @@ public class FileUtilsTest extends AbstractTempDirTest {
assertTrue(expectedSize > 0, "Size > 0");
}
- // toURLs
+// @Test public void testToURLs2() throws Exception {
+// File[] files = new File[] {
+// new File(temporaryFolder, "file1.txt"),
+// null,
+// };
+// URL[] urls = FileUtils.toURLs(files);
+//
+// assertEquals(files.length, urls.length);
+// assertTrue(urls[0].toExternalForm().startsWith("file:"));
+// assertTrue(urls[0].toExternalForm().indexOf("file1.txt") > 0);
+// assertEquals(null, urls[1]);
+// }
+//
+// @Test public void testToURLs3() throws Exception {
+// File[] files = null;
+// URL[] urls = FileUtils.toURLs(files);
+//
+// assertEquals(0, urls.length);
+// }
@Test
public void testCopyDirectoryToDirectory_NonExistingDest() throws
Exception {
@@ -885,26 +904,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
FileUtils.deleteDirectory(destDir);
}
-// @Test public void testToURLs2() throws Exception {
-// File[] files = new File[] {
-// new File(temporaryFolder, "file1.txt"),
-// null,
-// };
-// URL[] urls = FileUtils.toURLs(files);
-//
-// assertEquals(files.length, urls.length);
-// assertTrue(urls[0].toExternalForm().startsWith("file:"));
-// assertTrue(urls[0].toExternalForm().indexOf("file1.txt") > 0);
-// assertEquals(null, urls[1]);
-// }
-//
-// @Test public void testToURLs3() throws Exception {
-// File[] files = null;
-// URL[] urls = FileUtils.toURLs(files);
-//
-// assertEquals(0, urls.length);
-// }
-
@Test
public void testCopyDirectoryToExistingDest() throws Exception {
if (!testFile1.getParentFile().exists()) {
@@ -946,8 +945,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
assertTrue(new File(destDir, "sub/A.txt").exists());
}
- // contentEquals
-
/* Test for IO-141 */
@Test
public void testCopyDirectoryToGrandChild() throws Exception {
@@ -973,8 +970,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
assertEquals(1, LIST_WALKER.list(dir).size());
}
- // copyURLToFile
-
@Test
public void testCopyDirectoryToNonExistingDest() throws Exception {
if (!testFile1.getParentFile().exists()) {
@@ -1029,8 +1024,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
assertEquals(getLastModifiedMillis(testFile1),
getLastModifiedMillis(destination), "Check last modified date preserved");
}
- // forceMkdir
-
@Test
public void testCopyFile1ToDir() throws Exception {
final File directory = new File(tempDirFile, "subdir");
@@ -1062,8 +1055,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
assertEquals(getLastModifiedMillis(testFile1) ,
getLastModifiedMillis(destination), "Check last modified date preserved");
}
- // sizeOfDirectory
-
@Test
public void testCopyFile2ToDir() throws Exception {
final File directory = new File(tempDirFile, "subdir");
@@ -1189,8 +1180,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
() -> FileUtils.copyToDirectory(new File(tempDirFile,
"doesNotExists"), tempDirFile));
}
- // copyFile
-
@Test
public void testCopyToDirectoryWithFileSourceIsNull() {
assertThrows(NullPointerException.class, () ->
FileUtils.copyToDirectory((File) null, tempDirFile));
@@ -1242,25 +1231,27 @@ public class FileUtilsTest extends AbstractTempDirTest {
public void testCopyURLToFile() throws Exception {
// Creates file
final File file = new File(tempDirFile, getName());
- file.deleteOnExit();
+ assertContentMatchesAfterCopyURLToFileFor("/java/lang/Object.class",
file);
+ //TODO Maybe test copy to itself like for copyFile()
+ }
- // Loads resource
- final String resourceName = "/java/lang/Object.class";
- FileUtils.copyURLToFile(getClass().getResource(resourceName), file);
+ @Test
+ public void testCopyURLToFileCreatesParentDirs() throws Exception {
+ final File file =
managedTempDirPath.resolve("subdir").resolve(getName()).toFile();
+ assertContentMatchesAfterCopyURLToFileFor("/java/lang/Object.class",
file);
+ }
- // Tests that resuorce was copied correctly
- try (InputStream fis = Files.newInputStream(file.toPath())) {
-
assertTrue(IOUtils.contentEquals(getClass().getResourceAsStream(resourceName),
fis),
- "Content is not equal.");
- }
- //TODO Maybe test copy to itself like for copyFile()
+ @Test
+ public void testCopyURLToFileReplacesExisting() throws Exception {
+ final File file = new File(tempDirFile, getName());
+ assertContentMatchesAfterCopyURLToFileFor("/java/lang/Object.class",
file);
+ assertContentMatchesAfterCopyURLToFileFor("/java/lang/String.class",
file);
}
@Test
public void testCopyURLToFileWithTimeout() throws Exception {
// Creates file
final File file = new File(tempDirFile,
"testCopyURLToFileWithTimeout");
- file.deleteOnExit();
// Loads resource
final String resourceName = "/java/lang/Object.class";
@@ -1495,7 +1486,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
// Creates test file
final File testFile = new File(tempDirFile, getName());
- testFile.deleteOnExit();
testFile.createNewFile();
assertTrue(testFile.exists(), "Test file does not exist.");
@@ -2489,7 +2479,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
// Creates file
file.createNewFile();
- file.deleteOnExit();
// New file
assertEquals(0, FileUtils.sizeOf(file));
@@ -2513,7 +2502,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
// Creates file
file.createNewFile();
- file.deleteOnExit();
// New file
assertEquals(BigInteger.ZERO, FileUtils.sizeOfAsBigInteger(file));
@@ -2564,7 +2552,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
// Creates file
file.createNewFile();
- file.deleteOnExit();
// Existing file
assertThrows(IllegalArgumentException.class, () ->
FileUtils.sizeOfDirectoryAsBigInteger(file));
@@ -2589,7 +2576,6 @@ public class FileUtilsTest extends AbstractTempDirTest {
} finally {
IOUtils.closeQuietly(output);
}
- nonEmptyFile.deleteOnExit();
assertEquals(TEST_DIRECTORY_SIZE_GT_ZERO_BI,
FileUtils.sizeOfDirectoryAsBigInteger(file), "Unexpected directory size");
diff --git
a/src/test/java/org/apache/commons/io/file/PathUtilsContentEqualsTest.java
b/src/test/java/org/apache/commons/io/file/PathUtilsContentEqualsTest.java
index 6fed6e8..71203b6 100644
--- a/src/test/java/org/apache/commons/io/file/PathUtilsContentEqualsTest.java
+++ b/src/test/java/org/apache/commons/io/file/PathUtilsContentEqualsTest.java
@@ -175,15 +175,12 @@ public class PathUtilsContentEqualsTest {
// Different files
final Path objFile1 = Paths.get(temporaryFolder.getAbsolutePath(),
getName() + ".object");
- objFile1.toFile().deleteOnExit();
PathUtils.copyFile(getClass().getResource("/java/lang/Object.class"),
objFile1);
final Path objFile1b = Paths.get(temporaryFolder.getAbsolutePath(),
getName() + ".object2");
- objFile1b.toFile().deleteOnExit();
PathUtils.copyFile(getClass().getResource("/java/lang/Object.class"),
objFile1b);
final Path objFile2 = Paths.get(temporaryFolder.getAbsolutePath(),
getName() + ".collection");
- objFile2.toFile().deleteOnExit();
PathUtils.copyFile(getClass().getResource("/java/util/Collection.class"),
objFile2);
assertFalse(PathUtils.fileContentEquals(objFile1, objFile2));