Add FileUtils.isEmptyDirectory(File).
MODIFY
src/changes/changes.xml
src/changes/changes.xml
@@ -130,6 +130,9 @@ The <action> type attribute can be add,update,fix,remove.
<action issue="IO-700" dev="ggregory" type="add" due-to="Gary Gregory">
Add FileUtils.moveFile(File, File, CopyOption...) #185.
</action>
+ <action issue="IO-700" dev="ggregory" type="add" due-to="Gary Gregory">
+ Add FileUtils.isEmptyDirectory(File).
+ </action>
<!-- UPDATES -->
<action dev="ggregory" type="update" due-to="Dependabot">
Update junit-jupiter from 5.6.2 to 5.7.0 #153.

MODIFY
src/main/java/org/apache/commons/io/FileUtils.java
src/main/java/org/apache/commons/io/FileUtils.java
@@ -1487,6 +1487,18 @@ public static String getUserDirectoryPath() {
return System.getProperty("user.home");
}
+ /**
+ * Tests whether the directory is empty.
+ *
+ * @param directory the directory to query.
+ * @return whether the directory is empty.
+ * @throws IOException if an I/O error occurs.
+ * @since 2.9.0
+ */
+ public static boolean isEmptyDirectory(final File directory) throws IOException {
+ return PathUtils.isEmptyDirectory(directory.toPath());
+ }
+
/**
* Tests if the specified {@code File} is newer than the specified {@code ChronoLocalDate}
* at the current time.

MODIFY
src/test/java/org/apache/commons/io/FileUtilsTestCase.java
src/test/java/org/apache/commons/io/FileUtilsTestCase.java
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.CopyOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.time.Instant;
import java.time.LocalDate;
import java.util.zip.Checksum;
import org.apache.commons.io.file.PathUtils;
+import org.apache.commons.io.file.PathUtilsIsEmptyTest;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.NameFileFilter;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.commons.io.test.TestUtils;
import org.apache.commons.lang3.SystemUtils;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -571,8 +575,6 @@ public void testCompareSizeOf() {
assertEquals(sizeLong1, sizeBig.longValue(), "longSize should equal BigSize");
}
- // toFiles
-
@Test
public void testContentEquals() throws Exception {
// Non-existent files
@@ -627,6 +629,8 @@ public void testContentEquals() throws Exception {
assertTrue(FileUtils.contentEquals(file, file2));
}
+ // toFiles
+
@Test
public void testContentEqualsIgnoreEOL() throws Exception {
// Non-existent files
@@ -797,8 +801,6 @@ public void testCopyDirectoryPreserveDates() throws Exception {
FileUtils.deleteDirectory(target);
}
- // toURLs
-
/* Test for IO-141 */
@Test
public void testCopyDirectoryToChild() throws Exception {
@@ -818,25 +820,7 @@ public void testCopyDirectoryToChild() throws Exception {
assertTrue(expectedSize > 0, "Size > 0");
}
-// @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);
-// }
+ // toURLs
@Test
public void testCopyDirectoryToDirectory_NonExistingDest() throws Exception {
@@ -882,7 +866,25 @@ public void testCopyDirectoryToDirectory_NonExistingDest() throws Exception {
FileUtils.deleteDirectory(destDir);
}
- // contentEquals
+// @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 {
@@ -925,6 +927,8 @@ public void testCopyDirectoryToExistingDest() throws Exception {
assertTrue(new File(destDir, "sub/A.txt").exists());
}
+ // contentEquals
+
/* Test for IO-141 */
@Test
public void testCopyDirectoryToGrandChild() throws Exception {
@@ -941,8 +945,6 @@ public void testCopyDirectoryToGrandChild() throws Exception {
assertTrue(expectedSize > 0, "Size > 0");
}
- // copyURLToFile
-
/* Test for IO-217 FileUtils.copyDirectoryToDirectory makes infinite loops */
@Test
public void testCopyDirectoryToItself() throws Exception {
@@ -952,6 +954,8 @@ public void testCopyDirectoryToItself() throws Exception {
assertEquals(1, LIST_WALKER.list(dir).size());
}
+ // copyURLToFile
+
@Test
public void testCopyDirectoryToNonExistingDest() throws Exception {
if (!testFile1.getParentFile().exists()) {
@@ -994,8 +998,6 @@ public void testCopyDirectoryToNonExistingDest() throws Exception {
FileUtils.deleteDirectory(destDir);
}
- // forceMkdir
-
@Test
public void testCopyFile1() throws Exception {
final File destination = new File(temporaryFolder, "copy1.txt");
@@ -1008,6 +1010,8 @@ public void testCopyFile1() throws Exception {
assertEquals(getLastModifiedMillis(testFile1), getLastModifiedMillis(destination), "Check last modified date preserved");
}
+ // forceMkdir
+
@Test
public void testCopyFile1ToDir() throws Exception {
final File directory = new File(temporaryFolder, "subdir");
@@ -1027,8 +1031,6 @@ public void testCopyFile1ToDir() throws Exception {
"Should not be able to copy a file into the same directory as itself");
}
- // sizeOfDirectory
-
@Test
public void testCopyFile2() throws Exception {
final File destination = new File(temporaryFolder, "copy2.txt");
@@ -1041,6 +1043,8 @@ public void testCopyFile2() throws Exception {
assertEquals(getLastModifiedMillis(testFile1) , getLastModifiedMillis(destination), "Check last modified date preserved");
}
+ // sizeOfDirectory
+
@Test
public void testCopyFile2ToDir() throws Exception {
final File directory = new File(temporaryFolder, "subdir");
@@ -1158,14 +1162,14 @@ public void testCopyToDirectoryWithFile() throws IOException {
assertEquals(testFile1Size, destination.length(), "Check Full Copy");
}
- // copyFile
-
@Test
public void testCopyToDirectoryWithFileSourceDoesNotExist() {
assertThrows(IOException.class,
() -> FileUtils.copyToDirectory(new File(temporaryFolder, "doesNotExists"), temporaryFolder));
}
+ // copyFile
+
@Test
public void testCopyToDirectoryWithFileSourceIsNull() {
assertThrows(NullPointerException.class, () -> FileUtils.copyToDirectory((File) null, temporaryFolder));
@@ -1361,8 +1365,6 @@ public void testDeleteQuietlyNonExistent() {
}
}
- // copyToDirectory
-
/*
* Test the FileUtils implementation.
*/
@@ -1393,6 +1395,8 @@ public void testFileUtils() throws Exception {
}
+ // copyToDirectory
+
@Test
public void testForceDeleteAFile1() throws Exception {
final File destination = new File(temporaryFolder, "copy1.txt");
@@ -1489,8 +1493,6 @@ public void testForceMkdirParent() throws Exception {
assertFalse(testFile.exists());
}
- // forceDelete
-
//-----------------------------------------------------------------------
@Test
public void testGetFile() {
@@ -1508,6 +1510,8 @@ public void testGetFile() {
}
}
+ // forceDelete
+
@Test
public void testGetFile_Parent() {
final File parent = new File("parent");
@@ -1537,28 +1541,28 @@ public void testGetTempDirectory() {
assertEquals(tempDirectory, FileUtils.getTempDirectory());
}
- // copyFileToDirectory
-
@Test
public void testGetTempDirectoryPath() {
assertEquals(System.getProperty("java.io.tmpdir"),
FileUtils.getTempDirectoryPath());
}
+ // copyFileToDirectory
+
@Test
public void testGetUserDirectory() {
final File userDirectory = new File(System.getProperty("user.home"));
assertEquals(userDirectory, FileUtils.getUserDirectory());
}
- // forceDelete
-
@Test
public void testGetUserDirectoryPath() {
assertEquals(System.getProperty("user.home"),
FileUtils.getUserDirectoryPath());
}
+ // forceDelete
+
// This test relies on FileUtils.copyFile using File.length to check the output size
@Test
public void testIncorrectOutputSize() throws Exception {
@@ -1601,6 +1605,18 @@ public void testIO300() throws Exception {
assertTrue(src.exists());
}
+ @Test
+ public void testIsEmptyDirectory() throws IOException {
+ final Path tempDir = Files.createTempDirectory(getClass().getCanonicalName());
+ final File tempDirAsFile = tempDir.toFile();
+ try {
+ Assertions.assertTrue(FileUtils.isEmptyDirectory(tempDirAsFile));
+ } finally {
+ Files.delete(tempDir);
+ }
+ Assertions.assertFalse(FileUtils.isEmptyDirectory(PathUtilsIsEmptyTest.DIR_SIZE_1.toFile()));
+ }
+
// isFileNewer / isFileOlder
@Test
public void testIsFileNewerOlder() throws Exception {

MODIFY
src/test/java/org/apache/commons/io/file/PathUtilsIsEmptyTest.java
src/test/java/org/apache/commons/io/file/PathUtilsIsEmptyTest.java
*/
public class PathUtilsIsEmptyTest {
- private static final Path DIR_SIZE_1 = Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1");
+ public static final Path DIR_SIZE_1 = Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1");
private static final Path FILE_SIZE_0 = Paths
.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-0/file-size-0.bin");

Add FileUtils.isEmptyDirectory(File).