From ab9b96dc58cc0729a925888fb197eae105ef8426 Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Sun, 23 Apr 2017 21:02:29 +0200 Subject: [PATCH] IO-367: Add convenience methods for copyToDirectory (closes #18) based on patch supplied by James Sawle --- .../java/org/apache/commons/io/FileUtils.java | 69 ++++++++++++++ .../apache/commons/io/FileUtilsTestCase.java | 89 +++++++++++++++++++ 2 files changed, 158 insertions(+) diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java index 51f82d7ff5e..10f39b976e2 100644 --- a/src/main/java/org/apache/commons/io/FileUtils.java +++ b/src/main/java/org/apache/commons/io/FileUtils.java @@ -1531,6 +1531,75 @@ public static void copyToFile(final InputStream source, final File destination) } } + /** + * Copies a file or directory to within another directory preserving the file dates. + *

+ * This method copies the source file or directory, along all its contents, to a + * directory of the same name in the specified destination directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: This method tries to preserve the files' last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + * + * @param src an existing file or directory to copy, must not be {@code null} + * @param destDir the directory to place the copy in, must not be {@code null} + * + * @throws NullPointerException if source or destination is {@code null} + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyDirectoryToDirectory(File, File) + * @see #copyFileToDirectory(File, File) + * @since 2.6 + */ + public static void copyToDirectory(final File src, final File destDir) throws IOException { + if (src == null) { + throw new NullPointerException("Source must not be null"); + } + if (src.isFile()) { + copyFileToDirectory(src, destDir); + } else if (src.isDirectory()) { + copyDirectoryToDirectory(src, destDir); + } else { + throw new IOException("The source " + src + " does not exist"); + } + } + + /** + * Copies a files to a directory preserving each file's date. + *

+ * This method copies the contents of the specified source files + * to a file of the same name in the specified destination directory. + * The destination directory is created if it does not exist. + * If the destination file exists, then this method will overwrite it. + *

+ * Note: This method tries to preserve the file's last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that the operation will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcs a existing files to copy, must not be {@code null} + * @param destDir the directory to place the copy in, must not be {@code null} + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFileToDirectory(File, File) + * @since 2.6 + */ + public static void copyToDirectory(final Iterable srcs, final File destDir) throws IOException { + if (srcs == null) { + throw new NullPointerException("Sources must not be null"); + } + for (File src : srcs) { + copyFileToDirectory(src, destDir); + } + } + //----------------------------------------------------------------------- /** * Deletes a directory recursively. diff --git a/src/test/java/org/apache/commons/io/FileUtilsTestCase.java b/src/test/java/org/apache/commons/io/FileUtilsTestCase.java index 04dc7f0b471..303b7c96c06 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsTestCase.java +++ b/src/test/java/org/apache/commons/io/FileUtilsTestCase.java @@ -1534,6 +1534,95 @@ public void testCopyDirectoryErrors() throws Exception { } } + // copyToDirectory + + @Test + public void testCopyToDirectoryWithFile() throws IOException { + final File directory = new File(getTestDirectory(), "subdir"); + if (!directory.exists()) { + directory.mkdirs(); + } + final File destination = new File(directory, testFile1.getName()); + + FileUtils.copyToDirectory(testFile1, directory); + assertTrue("Check Exists", destination.exists()); + assertEquals("Check Full Copy", testFile1Size, destination.length()); + } + + @Test(expected=NullPointerException.class) + public void testCopyToDirectoryWithFileSourceIsNull() throws IOException { + FileUtils.copyToDirectory((File) null, getTestDirectory()); + } + + @Test(expected=IOException.class) + public void testCopyToDirectoryWithFileSourceDoesNotExist() throws IOException { + FileUtils.copyToDirectory(new File(getTestDirectory(), "doesNotExists"), getTestDirectory()); + } + + @Test + public void testCopyToDirectoryWithDirectory() throws IOException { + final File destDirectory = new File(getTestDirectory(), "destination"); + if (!destDirectory.exists()) { + destDirectory.mkdirs(); + } + + // Create a test directory + final File inputDirectory = new File(getTestDirectory(), "input"); + if (!inputDirectory.exists()) { + inputDirectory.mkdirs(); + } + final File outputDirDestination = new File(destDirectory, inputDirectory.getName()); + FileUtils.copyToDirectory(testFile1, inputDirectory); + final File destFile1 = new File(outputDirDestination, testFile1.getName()); + FileUtils.copyToDirectory(testFile2, inputDirectory); + final File destFile2 = new File(outputDirDestination, testFile2.getName()); + + FileUtils.copyToDirectory(inputDirectory, destDirectory); + + // Check the directory was created + assertTrue("Check Exists", outputDirDestination.exists()); + assertTrue("Check Directory", outputDirDestination.isDirectory()); + + // Check each file + assertTrue("Check Exists", destFile1.exists()); + assertEquals("Check Full Copy", testFile1Size, destFile1.length()); + assertTrue("Check Exists", destFile2.exists()); + assertEquals("Check Full Copy", testFile2Size, destFile2.length()); + } + + @Test + public void testCopyToDirectoryWithIterable() throws IOException { + final File directory = new File(getTestDirectory(), "subdir"); + if (!directory.exists()) { + directory.mkdirs(); + } + + List input = new ArrayList<>(); + input.add(testFile1); + input.add(testFile2); + + final File destFile1 = new File(directory, testFile1.getName()); + final File destFile2 = new File(directory, testFile2.getName()); + + FileUtils.copyToDirectory(input, directory); + // Check each file + assertTrue("Check Exists", destFile1.exists()); + assertEquals("Check Full Copy", testFile1Size, destFile1.length()); + assertTrue("Check Exists", destFile2.exists()); + assertEquals("Check Full Copy", testFile2Size, destFile2.length()); + } + + @Test(expected=NullPointerException.class) + public void testCopyToDirectoryWithIterableSourceIsNull() throws IOException { + FileUtils.copyToDirectory((List) null, getTestDirectory()); + } + + @Test(expected=IOException.class) + public void testCopyToDirectoryWithIterableSourceDoesNotExist() throws IOException { + FileUtils.copyToDirectory(Collections.singleton(new File(getTestDirectory(), "doesNotExists")), + getTestDirectory()); + } + // forceDelete @Test