Add and use PathUtils.sizeOf(Path)
Add and use PathUtils.sizeOfAsBigInteger(Path)
Add and use PathUtils.sizeOfDirectory(Path)
Add and use PathUtils.sizeOfDirectoryAsBigInteger(Path)
Use assertThrows in tests.
MODIFY
src/changes/changes.xml
src/changes/changes.xml
@@ -190,6 +190,12 @@ The <action> type attribute can be add,update,fix,remove.
Add and use PathUtils.isOlder(Path, long, LinkOption...)
Add and use PathUtils.isOlder(Path, Path)
</action>
+ <action dev="ggregory" type="add" due-to="Gary Gregory">
+ Add and use PathUtils.sizeOf(Path)
+ Add and use PathUtils.sizeOfAsBigInteger(Path)
+ Add and use PathUtils.sizeOfDirectory(Path)
+ Add and use PathUtils.sizeOfDirectoryAsBigInteger(Path)
+ </action>
<!-- UPDATE -->
<action dev="ggregory" type="add" due-to="Gary Gregory">
Update FileEntry to use FileTime instead of long for file time stamps.

MODIFY
src/main/java/org/apache/commons/io/FileUtils.java
src/main/java/org/apache/commons/io/FileUtils.java
@@ -2184,7 +2184,7 @@ public static LineIterator lineIterator(final File file) throws IOException {
public static LineIterator lineIterator(final File file, final String charsetName) throws IOException {
InputStream inputStream = null;
try {
- inputStream = openInputStream(file);
+ inputStream = Files.newInputStream(file.toPath());
return IOUtils.lineIterator(inputStream, charsetName);
} catch (final IOException | RuntimeException ex) {
IOUtils.closeQuietly(inputStream, ex::addSuppressed);
@@ -2644,7 +2644,7 @@ public static String readFileToString(final File file) throws IOException {
* @since 2.3
*/
public static String readFileToString(final File file, final Charset charsetName) throws IOException {
- try (InputStream inputStream = openInputStream(file)) {
+ try (InputStream inputStream = Files.newInputStream(file.toPath())) {
return IOUtils.toString(inputStream, Charsets.toCharset(charsetName));
}
}
@@ -2699,9 +2699,7 @@ public static String readFileToString(final File file, final String charsetName)
* @since 2.3
*/
public static List<String> readLines(final File file, final Charset charset) throws IOException {
- try (InputStream inputStream = openInputStream(file)) {
- return IOUtils.readLines(inputStream, Charsets.toCharset(charset));
- }
+ return Files.readAllLines(file.toPath(), charset);
}
/**
@@ -2960,27 +2958,18 @@ private static void setLastModified(final File file, final long timeMillis) thro
*
* @throws NullPointerException if the file is {@code null}.
* @throws IllegalArgumentException if the file does not exist.
+ * @throws UncheckedIOException if an IO error occurs.
*
* @since 2.0
*/
public static long sizeOf(final File file) {
requireExists(file, "file");
- return file.isDirectory() ? sizeOfDirectory0(file) : file.length();
- }
-
- /**
- * Gets the size of a file.
- *
- * @param file the file to check.
- * @return the size of the file.
- * @throws NullPointerException if the file is {@code null}.
- */
- private static long sizeOf0(final File file) {
- Objects.requireNonNull(file, "file");
- if (file.isDirectory()) {
- return sizeOfDirectory0(file);
+ try {
+ return PathUtils.sizeOf(file.toPath());
+ } catch (IOException e) {
+ // TODO Update method signature
+ throw new UncheckedIOException(e);
}
- return file.length(); // will be 0 if file does not exist
}
/**
@@ -2998,23 +2987,18 @@ private static long sizeOf0(final File file) {
*
* @throws NullPointerException if the file is {@code null}.
* @throws IllegalArgumentException if the file does not exist.
+ * @throws UncheckedIOException if an IO error occurs.
*
* @since 2.4
*/
public static BigInteger sizeOfAsBigInteger(final File file) {
requireExists(file, "file");
- return file.isDirectory() ? sizeOfDirectoryBig0(file) : BigInteger.valueOf(file.length());
+ try {
+ return PathUtils.sizeOfAsBigInteger(file.toPath());
+ } catch (IOException e) {
+ // TODO Update method signature
+ throw new UncheckedIOException(e);
}
-
- /**
- * Returns the size of a file or directory.
- *
- * @param file The file or directory.
- * @return the size
- */
- private static BigInteger sizeOfBig0(final File file) {
- Objects.requireNonNull(file, "fileOrDir");
- return file.isDirectory() ? sizeOfDirectoryBig0(file) : BigInteger.valueOf(file.length());
}
/**
@@ -3029,36 +3013,16 @@ private static BigInteger sizeOfBig0(final File file) {
* @return size of directory in bytes, 0 if directory is security restricted, a negative number when the real total
* is greater than {@link Long#MAX_VALUE}.
* @throws NullPointerException if the directory is {@code null}.
+ * @throws UncheckedIOException if an IO error occurs.
*/
public static long sizeOfDirectory(final File directory) {
- return sizeOfDirectory0(requireDirectoryExists(directory, "directory"));
- }
-
- /**
- * Gets the size of a directory.
- *
- * @param directory the directory to check
- * @return the size
- * @throws NullPointerException if the directory is {@code null}.
- */
- private static long sizeOfDirectory0(final File directory) {
- Objects.requireNonNull(directory, "directory");
- final File[] files = directory.listFiles();
- if (files == null) { // null if security restricted
- return 0L;
- }
- long size = 0;
-
- for (final File file : files) {
- if (!isSymlink(file)) {
- size += sizeOf0(file);
- if (size < 0) {
- break;
- }
- }
+ requireDirectoryExists(directory, "directory");
+ try {
+ return PathUtils.sizeOfDirectory(directory.toPath());
+ } catch (IOException e) {
+ // TODO Update method signature
+ throw new UncheckedIOException(e);
}
-
- return size;
}
/**
@@ -3067,34 +3031,18 @@ private static long sizeOfDirectory0(final File directory) {
* @param directory directory to inspect, must not be {@code null}.
* @return size of directory in bytes, 0 if directory is security restricted.
* @throws NullPointerException if the directory is {@code null}.
+ * @throws UncheckedIOException if an IO error occurs.
* @since 2.4
*/
public static BigInteger sizeOfDirectoryAsBigInteger(final File directory) {
- return sizeOfDirectoryBig0(requireDirectoryExists(directory, "directory"));
- }
-
- /**
- * Computes the size of a directory.
- *
- * @param directory The directory.
- * @return the size.
- */
- private static BigInteger sizeOfDirectoryBig0(final File directory) {
- Objects.requireNonNull(directory, "directory");
- final File[] files = directory.listFiles();
- if (files == null) {
- // null if security restricted
- return BigInteger.ZERO;
- }
- BigInteger size = BigInteger.ZERO;
-
- for (final File file : files) {
- if (!isSymlink(file)) {
- size = size.add(sizeOfBig0(file));
- }
+ requireDirectoryExists(directory, "directory");
+ try {
+ return PathUtils.sizeOfDirectoryAsBigInteger(directory.toPath());
+ } catch (IOException e) {
+ // TODO Update method signature
+ throw new UncheckedIOException(e);
}
- return size;
}
/**

MODIFY
src/main/java/org/apache/commons/io/file/PathUtils.java
src/main/java/org/apache/commons/io/file/PathUtils.java
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
+import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
@@ -305,7 +306,18 @@ public static Path copyFileToDirectory(final URL sourceFile, final Path targetDi
* @throws IOException if an I/O error is thrown by a visitor method.
*/
public static PathCounters countDirectory(final Path directory) throws IOException {
- return visitFileTree(new CountingPathVisitor(Counters.longPathCounters()), directory).getPathCounters();
+ return visitFileTree(CountingPathVisitor.withLongCounters(), directory).getPathCounters();
+ }
+
+ /**
+ * Counts aspects of a directory including sub-directories.
+ *
+ * @param directory directory to delete.
+ * @return The visitor used to count the given directory.
+ * @throws IOException if an I/O error is thrown by a visitor method.
+ */
+ public static PathCounters countDirectoryAsBigInteger(final Path directory) throws IOException {
+ return visitFileTree(CountingPathVisitor.withBigIntegerCounters(), directory).getPathCounters();
}
/**
@@ -499,7 +511,7 @@ public static PathCounters deleteFile(final Path file, final LinkOption[] linkOp
* @param path1 The first directory.
* @param path2 The second directory.
* @return Whether the two directories contain the same files while considering file contents.
- * @throws IOException if an I/O error is thrown by a visitor method
+ * @throws IOException if an I/O error is thrown by a visitor method.
*/
public static boolean directoryAndFileContentEquals(final Path path1, final Path path2) throws IOException {
return directoryAndFileContentEquals(path1, path2, EMPTY_LINK_OPTION_ARRAY, EMPTY_OPEN_OPTION_ARRAY, EMPTY_FILE_VISIT_OPTION_ARRAY);
@@ -515,7 +527,7 @@ public static boolean directoryAndFileContentEquals(final Path path1, final Path
* @param openOptions options to open files.
* @param fileVisitOption options to configure traversal.
* @return Whether the two directories contain the same files while considering file contents.
- * @throws IOException if an I/O error is thrown by a visitor method
+ * @throws IOException if an I/O error is thrown by a visitor method.
*/
public static boolean directoryAndFileContentEquals(final Path path1, final Path path2, final LinkOption[] linkOptions, final OpenOption[] openOptions,
final FileVisitOption[] fileVisitOption) throws IOException {
@@ -556,7 +568,7 @@ public static boolean directoryAndFileContentEquals(final Path path1, final Path
* @param path1 The first directory.
* @param path2 The second directory.
* @return Whether the two directories contain the same files without considering file contents.
- * @throws IOException if an I/O error is thrown by a visitor method
+ * @throws IOException if an I/O error is thrown by a visitor method.
*/
public static boolean directoryContentEquals(final Path path1, final Path path2) throws IOException {
return directoryContentEquals(path1, path2, Integer.MAX_VALUE, EMPTY_LINK_OPTION_ARRAY, EMPTY_FILE_VISIT_OPTION_ARRAY);
@@ -572,7 +584,7 @@ public static boolean directoryContentEquals(final Path path1, final Path path2)
* @param linkOptions options to follow links.
* @param fileVisitOptions options to configure the traversal
* @return Whether the two directories contain the same files without considering file contents.
- * @throws IOException if an I/O error is thrown by a visitor method
+ * @throws IOException if an I/O error is thrown by a visitor method.
*/
public static boolean directoryContentEquals(final Path path1, final Path path2, final int maxDepth, final LinkOption[] linkOptions,
final FileVisitOption[] fileVisitOptions) throws IOException {
@@ -1122,6 +1134,94 @@ public static Path setReadOnly(final Path path, final boolean readOnly, final Li
throw new IOException(String.format("No DosFileAttributeView or PosixFileAttributeView for '%s' (linkOptions=%s)", path, Arrays.toString(linkOptions)));
}
+ /**
+ * Returns the size of the specified file or directory. If the provided {@link File} is a regular file, then the file's
+ * length is returned. If the argument is a directory, then the size of the directory is calculated recursively. If a
+ * directory or subdirectory is security restricted, its size will not be included.
+ * <p>
+ * Note that overflow is not detected, and the return value may be negative if overflow occurs. See
+ * {@link #sizeOfAsBigInteger(Path)} for an alternative method that does not overflow.
+ * </p>
+ *
+ * @param path the regular file or directory to return the size of (must not be {@code null}).
+ * @return the length of the file, or recursive size of the directory, provided (in bytes).
+ * @throws NullPointerException if the file is {@code null}.
+ * @throws IllegalArgumentException if the file does not exist.
+ * @throws IOException if an I/O error occurs.
+ *
+ * @since 2.12.0
+ */
+ public static long sizeOf(final Path path) throws IOException {
+ requireExists(path, "path");
+ return Files.isDirectory(path) ? sizeOfDirectory(path) : Files.size(path);
+ }
+
+ /**
+ * Returns the size of the specified file or directory. If the provided {@link Path} is a regular file, then the file's
+ * length is returned. If the argument is a directory, then the size of the directory is calculated recursively. If a
+ * directory or subdirectory is security restricted, its size will not be included.
+ *
+ * @param path the regular file or directory to return the size of (must not be {@code null}).
+ * @return the length of the file, or recursive size of the directory, provided (in bytes).
+ * @throws NullPointerException if the file is {@code null}.
+ * @throws IllegalArgumentException if the file does not exist.
+ * @throws IOException if an I/O error occurs.
+ *
+ * @since 2.12.0
+ */
+ public static BigInteger sizeOfAsBigInteger(final Path path) throws IOException {
+ requireExists(path, "path");
+ return Files.isDirectory(path) ? sizeOfDirectoryAsBigInteger(path) : BigInteger.valueOf(Files.size(path));
+ }
+
+ /**
+ * Counts the size of a directory recursively (sum of the length of all files).
+ * <p>
+ * Note that overflow is not detected, and the return value may be negative if overflow occurs. See
+ * {@link #sizeOfDirectoryAsBigInteger(Path)} for an alternative method that does not overflow.
+ * </p>
+ *
+ * @param directory directory to inspect, must not be {@code null}.
+ * @return size of directory in bytes, 0 if directory is security restricted, a negative number when the real total is
+ * greater than {@link Long#MAX_VALUE}.
+ * @throws NullPointerException if the directory is {@code null}.
+ * @throws IOException if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static long sizeOfDirectory(final Path directory) throws IOException {
+ return countDirectory(directory).getByteCounter().getLong();
+ }
+
+ /**
+ * Counts the size of a directory recursively (sum of the length of all files).
+ *
+ * @param directory directory to inspect, must not be {@code null}.
+ * @return size of directory in bytes, 0 if directory is security restricted.
+ * @throws NullPointerException if the directory is {@code null}.
+ * @throws IOException if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static BigInteger sizeOfDirectoryAsBigInteger(final Path directory) throws IOException {
+ return countDirectoryAsBigInteger(directory).getByteCounter().getBigInteger();
+ }
+
+ /**
+ * Requires that the given {@code File} exists and throws an {@link IllegalArgumentException} if it doesn't.
+ *
+ * @param file The {@code File} to check.
+ * @param fileParamName The parameter name to use in the exception message in case of {@code null} input.
+ * @return the given file.
+ * @throws NullPointerException if the given {@code File} is {@code null}.
+ * @throws IllegalArgumentException if the given {@code File} does not exist.
+ */
+ private static Path requireExists(final Path file, final String fileParamName) {
+ Objects.requireNonNull(file, fileParamName);
+ if (!Files.exists(file)) {
+ throw new IllegalArgumentException("File system element for parameter '" + fileParamName + "' does not exist: '" + file + "'");
+ }
+ return file;
+ }
+
/**
* Converts an array of {@link FileVisitOption} to a {@link Set}.
*
@@ -1142,9 +1242,10 @@ public static Path setReadOnly(final Path path, final boolean readOnly, final Li
* @param <T> See {@link Files#walkFileTree(Path,FileVisitor)}.
* @return the given visitor.
*
- * @throws IOException if an I/O error is thrown by a visitor method
+ * @throws IOException if an I/O error is thrown by a visitor method.
*/
public static <T extends FileVisitor<? super Path>> T visitFileTree(final T visitor, final Path directory) throws IOException {
+ requireExists(directory, "directory");
Files.walkFileTree(directory, visitor);
return visitor;
}
@@ -1161,7 +1262,7 @@ public static Path setReadOnly(final Path path, final boolean readOnly, final Li
* @param <T> See {@link Files#walkFileTree(Path,Set,int,FileVisitor)}.
* @return the given visitor.
*
- * @throws IOException if an I/O error is thrown by a visitor method
+ * @throws IOException if an I/O error is thrown by a visitor method.
*/
public static <T extends FileVisitor<? super Path>> T visitFileTree(final T visitor, final Path start, final Set<FileVisitOption> options,
final int maxDepth) throws IOException {
@@ -1180,7 +1281,7 @@ public static Path setReadOnly(final Path path, final boolean readOnly, final Li
* @param <T> See {@link Files#walkFileTree(Path,FileVisitor)}.
* @return the given visitor.
*
- * @throws IOException if an I/O error is thrown by a visitor method
+ * @throws IOException if an I/O error is thrown by a visitor method.
*/
public static <T extends FileVisitor<? super Path>> T visitFileTree(final T visitor, final String first, final String... more) throws IOException {
return visitFileTree(visitor, Paths.get(first, more));
@@ -1196,7 +1297,7 @@ public static Path setReadOnly(final Path path, final boolean readOnly, final Li
* @param <T> See {@link Files#walkFileTree(Path,FileVisitor)}.
* @return the given visitor.
*
- * @throws IOException if an I/O error is thrown by a visitor method
+ * @throws IOException if an I/O error is thrown by a visitor method.
*/
public static <T extends FileVisitor<? super Path>> T visitFileTree(final T visitor, final URI uri) throws IOException {
return visitFileTree(visitor, Paths.get(uri));

MODIFY
src/test/java/org/apache/commons/io/FileUtilsTestCase.java
src/test/java/org/apache/commons/io/FileUtilsTestCase.java
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.Instant;
import java.time.LocalDate;
@@ -3227,4 +3228,36 @@ public void testWriteWithEncoding_WithAppendOptionTrue_ShouldNotDeletePreviousFi
assertEquals(expected, actual);
}
+ /**
+ * Tests a directory with one file of size 0.
+ */
+ @Test
+ public void testCountFolders1FileSize0() throws IOException {
+ assertEquals(0, FileUtils.sizeOfDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-0").toFile()));
+ }
+
+ /**
+ * Tests a directory with one file of size 1.
+ */
+ @Test
+ public void testCountFolders1FileSize1() throws IOException {
+ assertEquals(1, FileUtils.sizeOfDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1").toFile()));
+ }
+
+ /**
+ * Tests a directory with two subdirectories, each containing one file of size 1.
+ */
+ @Test
+ public void testCountFolders2FileSize2() throws IOException {
+ assertEquals(2, FileUtils.sizeOfDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-2").toFile()));
+ }
+
+ /**
+ * Tests a directory with two subdirectories, each containing one file of size 1.
+ */
+ @Test
+ public void testCountFolders2FileSize4() throws IOException {
+ assertEquals(8, FileUtils.sizeOfDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-4").toFile()));
+ }
+
}

MODIFY
src/test/java/org/apache/commons/io/LineIteratorTestCase.java
src/test/java/org/apache/commons/io/LineIteratorTestCase.java
import java.io.StringReader;
import java.nio.charset.UnsupportedCharsetException;
import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
@@ -112,9 +113,8 @@ private void assertLines(final List<String> lines, final LineIterator iterator)
@Test
public void testConstructor() {
assertThrows(IllegalArgumentException.class, () -> {
- try (
- LineIterator li = new LineIterator(null)
- ) { }
+ try (LineIterator li = new LineIterator(null)) {
+ }
});
}
@@ -141,14 +141,7 @@ public void testThreeLines() throws Exception {
@Test
public void testMissingFile() throws Exception {
final File testFile = new File(temporaryFolder, "dummy-missing-file.txt");
-
- try (
- LineIterator iterator = FileUtils.lineIterator(testFile, "UTF-8")
- ){
- fail("Expected FileNotFoundException");
- } catch (final FileNotFoundException expected) {
- // ignore, expected result
- }
+ assertThrows(NoSuchFileException.class, () -> FileUtils.lineIterator(testFile, "UTF-8"));
}
@Test
@@ -158,9 +151,7 @@ public void testValidEncoding() throws Exception {
final File testFile = new File(temporaryFolder, "LineIterator-validEncoding.txt");
createLinesFile(testFile, encoding, 3);
- try (
- final LineIterator iterator = FileUtils.lineIterator(testFile, encoding)
- ){
+ try (final LineIterator iterator = FileUtils.lineIterator(testFile, encoding)) {
int count = 0;
while (iterator.hasNext()) {
assertNotNull(iterator.next());
@@ -177,13 +168,7 @@ public void testInvalidEncoding() throws Exception {
final File testFile = new File(temporaryFolder, "LineIterator-invalidEncoding.txt");
createLinesFile(testFile, "UTF-8", 3);
- try (
- LineIterator iterator = FileUtils.lineIterator(testFile, encoding)
- ) {
- fail("Expected UnsupportedCharsetException");
- } catch (final UnsupportedCharsetException expected) {
- // ignore, expected result
- }
+ assertThrows(UnsupportedCharsetException.class, () -> FileUtils.lineIterator(testFile, encoding));
}
@Test
@@ -224,9 +209,7 @@ public void testNextOnly() throws Exception {
final File testFile = new File(temporaryFolder, "LineIterator-nextOnly.txt");
final List<String> lines = createLinesFile(testFile, encoding, 3);
- try (
- final LineIterator iterator = FileUtils.lineIterator(testFile, encoding)
- ){
+ try (final LineIterator iterator = FileUtils.lineIterator(testFile, encoding)) {
for (int i = 0; i < lines.size(); i++) {
final String line = iterator.next();
assertEquals(lines.get(i), line, "next() line " + i);
@@ -243,9 +226,7 @@ public String readLine() throws IOException {
throw new IOException("hasNext");
}
};
- try (
- LineIterator li = new LineIterator(reader)
- ) {
+ try (LineIterator li = new LineIterator(reader)) {
assertThrows(IllegalStateException.class, () -> {
li.hasNext();
});
@@ -259,9 +240,7 @@ public void testCloseEarly() throws Exception {
final File testFile = new File(temporaryFolder, "LineIterator-closeEarly.txt");
createLinesFile(testFile, encoding, 3);
- try (
- final LineIterator iterator = FileUtils.lineIterator(testFile, encoding)
- ) {
+ try (final LineIterator iterator = FileUtils.lineIterator(testFile, encoding)) {
// get
assertNotNull("Line expected", iterator.next());
assertTrue(iterator.hasNext(), "More expected");
@@ -269,33 +248,12 @@ public void testCloseEarly() throws Exception {
// close
iterator.close();
assertFalse(iterator.hasNext(), "No more expected");
- try {
- iterator.next();
- fail();
- } catch (final NoSuchElementException ex) {
- // expected
- }
- try {
- iterator.nextLine();
- fail();
- } catch (final NoSuchElementException ex) {
- // expected
- }
-
+ assertThrows(NoSuchElementException.class, iterator::next);
+ assertThrows(NoSuchElementException.class, iterator::nextLine);
// try closing again
iterator.close();
- try {
- iterator.next();
- fail();
- } catch (final NoSuchElementException ex) {
- // expected
- }
- try {
- iterator.nextLine();
- fail();
- } catch (final NoSuchElementException ex) {
- // expected
- }
+ assertThrows(NoSuchElementException.class, iterator::next);
+ assertThrows(NoSuchElementException.class, iterator::nextLine);
}
}
@@ -313,15 +271,8 @@ private void doTestFileWithSpecifiedLines(final int lineCount) throws IOExceptio
final File testFile = new File(temporaryFolder, fileName);
final List<String> lines = createLinesFile(testFile, encoding, lineCount);
- try (
- final LineIterator iterator = FileUtils.lineIterator(testFile, encoding)
- ){
- try {
- iterator.remove();
- fail("Remove is unsupported");
- } catch (final UnsupportedOperationException ex) {
- // expected
- }
+ try (final LineIterator iterator = FileUtils.lineIterator(testFile, encoding)) {
+ assertThrows(UnsupportedOperationException.class, iterator::remove);
int idx = 0;
while (iterator.hasNext()) {
@@ -333,18 +284,8 @@ private void doTestFileWithSpecifiedLines(final int lineCount) throws IOExceptio
assertEquals(idx, lines.size(), "Line Count doesn't match");
// try calling next() after file processed
- try {
- iterator.next();
- fail("Expected NoSuchElementException");
- } catch (final NoSuchElementException expected) {
- // ignore, expected result
- }
- try {
- iterator.nextLine();
- fail("Expected NoSuchElementException");
- } catch (final NoSuchElementException expected) {
- // ignore, expected result
- }
+ assertThrows(NoSuchElementException.class, iterator::next);
+ assertThrows(NoSuchElementException.class, iterator::nextLine);
}
}
@@ -382,12 +323,7 @@ protected boolean isValidLine(final String line) {
}
};
try {
- try {
- iterator.remove();
- fail("Remove is unsupported");
- } catch (final UnsupportedOperationException ex) {
- // expected
- }
+ assertThrows(UnsupportedOperationException.class, iterator::remove);
int idx = 0;
int actualLines = 0;
@@ -406,18 +342,8 @@ protected boolean isValidLine(final String line) {
assertEquals(6, actualLines, "Line Count doesn't match");
// try calling next() after file processed
- try {
- iterator.next();
- fail("Expected NoSuchElementException");
- } catch (final NoSuchElementException expected) {
- // ignore, expected result
- }
- try {
- iterator.nextLine();
- fail("Expected NoSuchElementException");
- } catch (final NoSuchElementException expected) {
- // ignore, expected result
- }
+ assertThrows(NoSuchElementException.class, iterator::next);
+ assertThrows(NoSuchElementException.class, iterator::nextLine);
} finally {
try {
IOUtils.close(iterator);

MODIFY
src/test/java/org/apache/commons/io/file/PathUtilsCountingTest.java
src/test/java/org/apache/commons/io/file/PathUtilsCountingTest.java
@@ -75,4 +75,14 @@ public void testCountFolders2FileSize2() throws IOException {
.countDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-2"));
assertCounts(3, 2, 2, pathCounts);
}
+
+ /**
+ * Tests a directory with two subdirectories, each containing one file of size 2.
+ */
+ @Test
+ public void testCountFolders2FileSize4() throws IOException {
+ final PathCounters pathCounts = PathUtils
+ .countDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-4"));
+ assertCounts(3, 4, 8, pathCounts);
+ }
}

ADD
src/test/resources/org/apache/commons/io/dirs-2-file-size-4/dirs-a-file-size-1/file-size-1.bin
+ab
\ No newline at end of file

ADD
src/test/resources/org/apache/commons/io/dirs-2-file-size-4/dirs-a-file-size-1/file-size-2.bin
+ac
\ No newline at end of file

ADD
src/test/resources/org/apache/commons/io/dirs-2-file-size-4/dirs-b-file-size-1/file-size-1.bin
+ab
\ No newline at end of file

ADD
src/test/resources/org/apache/commons/io/dirs-2-file-size-4/dirs-b-file-size-1/file-size-2.bin
+ac
\ No newline at end of file

Add and use PathUtils.sizeOf(Path)

- Add and use PathUtils.sizeOfAsBigInteger(Path)
- Add and use PathUtils.sizeOfDirectory(Path)
- Add and use PathUtils.sizeOfDirectoryAsBigInteger(Path)
- Use assertThrows in tests.